diff --git a/.eslintrc.js b/.eslintrc.js index 33be8cb62fcd..0d941f5a66b4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -119,6 +119,7 @@ module.exports = { // This path is provide alias for files like `ONYXKEYS` and `CONST`. '@src': './src', '@desktop': './desktop', + '@github': './.github', }, }, ], diff --git a/.github/actions/javascript/authorChecklist/authorChecklist.ts b/.github/actions/javascript/authorChecklist/authorChecklist.ts index 6f5f39c79f3d..f855c135cd39 100644 --- a/.github/actions/javascript/authorChecklist/authorChecklist.ts +++ b/.github/actions/javascript/authorChecklist/authorChecklist.ts @@ -1,8 +1,9 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import * as core from '@actions/core'; import * as github from '@actions/github'; import escapeRegExp from 'lodash/escapeRegExp'; -import CONST from '../../../libs/CONST'; -import GithubUtils from '../../../libs/GithubUtils'; +import CONST from '@github/libs/CONST'; +import GithubUtils from '@github/libs/GithubUtils'; import newComponentCategory from './categories/newComponentCategory'; const pathToAuthorChecklist = `https://raw.githubusercontent.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}/main/.github/PULL_REQUEST_TEMPLATE.md`; @@ -20,24 +21,24 @@ const CHECKLIST_CATEGORIES = { */ async function getChecklistCategoriesForPullRequest(): Promise> { const checks = new Set(); - const changedFiles = await GithubUtils.paginate(GithubUtils.octokit.pulls.listFiles, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - // eslint-disable-next-line @typescript-eslint/naming-convention - pull_number: prNumber, - // eslint-disable-next-line @typescript-eslint/naming-convention - per_page: 100, - }); - const possibleCategories = await Promise.all( - Object.values(CHECKLIST_CATEGORIES).map(async (category) => ({ - items: category.items, - doesCategoryApply: await category.detect(changedFiles), - })), - ); - for (const category of possibleCategories) { - if (category.doesCategoryApply) { - for (const item of category.items) { - checks.add(item); + if (prNumber !== undefined) { + const changedFiles = await GithubUtils.paginate(GithubUtils.octokit.pulls.listFiles, { + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + pull_number: prNumber, + per_page: 100, + }); + const possibleCategories = await Promise.all( + Object.values(CHECKLIST_CATEGORIES).map(async (category) => ({ + items: category.items, + doesCategoryApply: await category.detect(changedFiles), + })), + ); + for (const category of possibleCategories) { + if (category.doesCategoryApply) { + for (const item of category.items) { + checks.add(item); + } } } } @@ -126,12 +127,11 @@ async function generateDynamicChecksAndCheckForCompletion() { const newBody = contentBeforeChecklist + checklistStartsWith + checklist + checklistEndsWith + contentAfterChecklist; // Update the PR body - if (didChecklistChange) { + if (didChecklistChange && prNumber !== undefined) { console.log('Checklist changed, updating PR...'); await GithubUtils.octokit.pulls.update({ owner: CONST.GITHUB_OWNER, repo: CONST.APP_REPO, - // eslint-disable-next-line @typescript-eslint/naming-convention pull_number: prNumber, body: newBody, }); diff --git a/.github/actions/javascript/authorChecklist/categories/newComponentCategory.ts b/.github/actions/javascript/authorChecklist/categories/newComponentCategory.ts index 405a687b5d3e..71c413e5003b 100644 --- a/.github/actions/javascript/authorChecklist/categories/newComponentCategory.ts +++ b/.github/actions/javascript/authorChecklist/categories/newComponentCategory.ts @@ -1,9 +1,9 @@ import github from '@actions/github'; import {parse} from '@babel/parser'; import traverse from '@babel/traverse'; -import CONST from '../../../../libs/CONST'; -import GithubUtils from '../../../../libs/GithubUtils'; -import promiseSome from '../../../../libs/promiseSome'; +import CONST from '@github/libs/CONST'; +import GithubUtils from '@github/libs/GithubUtils'; +import promiseSome from '@github/libs/promiseSome'; import type Category from './Category'; type SuperClassType = {superClass: {name?: string; object: {name: string}; property: {name: string}} | null; name: string}; @@ -81,7 +81,7 @@ async function detectReactComponentInFile(filename: string): Promise { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); - -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); - -/** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} - */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; - } - this.initOctokit(); - return this.internalOctokit.graphql; - } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; - } - this.initOctokit(); - return this.internalOctokit.paginate; - } - - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } - - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } - - return this.getStagingDeployCashData(data[0]); - }); - } - - /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} - */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - - /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] - */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); - } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); - } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); - } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - /***/ }), /***/ 7351: @@ -11466,137 +10920,6 @@ jsesc.version = '2.5.2'; module.exports = jsesc; -/***/ }), - -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; - - -/***/ }), - -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), - -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); - -module.exports = Map; - - -/***/ }), - -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; - - /***/ }), /***/ 9213: @@ -11638,65 +10961,6 @@ function arrayMap(array, iteratee) { module.exports = arrayMap; -/***/ }), - -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var eq = __nccwpck_require__(1901); - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -module.exports = assocIndexOf; - - -/***/ }), - -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); - -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} - -module.exports = baseGet; - - /***/ }), /***/ 7497: @@ -11732,60 +10996,6 @@ function baseGetTag(value) { module.exports = baseGetTag; -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -module.exports = baseIsNative; - - /***/ }), /***/ 6792: @@ -11830,47 +11040,6 @@ function baseToString(value) { module.exports = baseToString; -/***/ }), - -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); - -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -module.exports = coreJsData; - - /***/ }), /***/ 2085: @@ -11882,55 +11051,6 @@ var freeGlobal = typeof global == 'object' && global && global.Object === Object module.exports = freeGlobal; -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - - -/***/ }), - -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -module.exports = getNative; - - /***/ }), /***/ 923: @@ -11984,572 +11104,6 @@ function getRawTag(value) { module.exports = getRawTag; -/***/ }), - -/***/ 3542: -/***/ ((module) => { - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -module.exports = getValue; - - -/***/ }), - -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} - -module.exports = hashClear; - - -/***/ }), - -/***/ 712: -/***/ ((module) => { - -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} - -module.exports = hashDelete; - - -/***/ }), - -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} - -module.exports = hashGet; - - -/***/ }), - -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), - -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -module.exports = hashSet; - - -/***/ }), - -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); - -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} - -module.exports = isKey; - - -/***/ }), - -/***/ 3308: -/***/ ((module) => { - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -module.exports = isKeyable; - - -/***/ }), - -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var coreJsData = __nccwpck_require__(8380); - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -module.exports = isMasked; - - -/***/ }), - -/***/ 9792: -/***/ ((module) => { - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} - -module.exports = listCacheClear; - - -/***/ }), - -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); - -/** Used for built-in method references. */ -var arrayProto = Array.prototype; - -/** Built-in value references. */ -var splice = arrayProto.splice; - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} - -module.exports = listCacheDelete; - - -/***/ }), - -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -module.exports = listCacheGet; - - -/***/ }), - -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), - -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -module.exports = listCacheSet; - - -/***/ }), - -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); - -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; - - -/***/ }), - -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getMapData = __nccwpck_require__(9980); - -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} - -module.exports = mapCacheDelete; - - -/***/ }), - -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getMapData = __nccwpck_require__(9980); - -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -module.exports = mapCacheGet; - - -/***/ }), - -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getMapData = __nccwpck_require__(9980); - -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -module.exports = mapCacheHas; - - -/***/ }), - -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getMapData = __nccwpck_require__(9980); - -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} - -module.exports = mapCacheSet; - - -/***/ }), - -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var memoize = __nccwpck_require__(9885); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; - -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; -} - -module.exports = memoizeCapped; - - -/***/ }), - -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479); - -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); - -module.exports = nativeCreate; - - /***/ }), /***/ 4200: @@ -12595,145 +11149,6 @@ var root = freeGlobal || freeSelf || Function('return this')(); module.exports = root; -/***/ }), - -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var memoizeCapped = __nccwpck_require__(9422); - -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; - -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - - -/***/ }), - -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isSymbol = __nccwpck_require__(6403); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = toKey; - - -/***/ }), - -/***/ 6928: -/***/ ((module) => { - -/** Used for built-in method references. */ -var funcProto = Function.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -module.exports = toSource; - - -/***/ }), - -/***/ 1901: -/***/ ((module) => { - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -module.exports = eq; - - /***/ }), /***/ 8415: @@ -12773,46 +11188,6 @@ function escapeRegExp(string) { module.exports = escapeRegExp; -/***/ }), - -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseGet = __nccwpck_require__(5758); - -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} - -module.exports = get; - - /***/ }), /***/ 4869: @@ -12846,88 +11221,6 @@ var isArray = Array.isArray; module.exports = isArray; -/***/ }), - -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); - -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -module.exports = isFunction; - - -/***/ }), - -/***/ 3334: -/***/ ((module) => { - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} - -module.exports = isObject; - - /***/ }), /***/ 5926: @@ -13000,86 +11293,6 @@ function isSymbol(value) { module.exports = isSymbol; -/***/ }), - -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var MapCache = __nccwpck_require__(938); - -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; - -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} - -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; - - /***/ }), /***/ 2931: @@ -18400,11 +16613,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); +/* eslint-disable @typescript-eslint/naming-convention */ const core = __importStar(__nccwpck_require__(2186)); const github = __importStar(__nccwpck_require__(5438)); const escapeRegExp_1 = __importDefault(__nccwpck_require__(8415)); const CONST_1 = __importDefault(__nccwpck_require__(4097)); -const GithubUtils_1 = __importDefault(__nccwpck_require__(7999)); +const GithubUtils_1 = __importDefault(__nccwpck_require__(9296)); const newComponentCategory_1 = __importDefault(__nccwpck_require__(9032)); const pathToAuthorChecklist = `https://raw.githubusercontent.com/${CONST_1.default.GITHUB_OWNER}/${CONST_1.default.APP_REPO}/main/.github/PULL_REQUEST_TEMPLATE.md`; const checklistStartsWith = '### PR Author Checklist'; @@ -18418,22 +16632,22 @@ const CHECKLIST_CATEGORIES = { */ async function getChecklistCategoriesForPullRequest() { const checks = new Set(); - const changedFiles = await GithubUtils_1.default.paginate(GithubUtils_1.default.octokit.pulls.listFiles, { - owner: CONST_1.default.GITHUB_OWNER, - repo: CONST_1.default.APP_REPO, - // eslint-disable-next-line @typescript-eslint/naming-convention - pull_number: prNumber, - // eslint-disable-next-line @typescript-eslint/naming-convention - per_page: 100, - }); - const possibleCategories = await Promise.all(Object.values(CHECKLIST_CATEGORIES).map(async (category) => ({ - items: category.items, - doesCategoryApply: await category.detect(changedFiles), - }))); - for (const category of possibleCategories) { - if (category.doesCategoryApply) { - for (const item of category.items) { - checks.add(item); + if (prNumber !== undefined) { + const changedFiles = await GithubUtils_1.default.paginate(GithubUtils_1.default.octokit.pulls.listFiles, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: prNumber, + per_page: 100, + }); + const possibleCategories = await Promise.all(Object.values(CHECKLIST_CATEGORIES).map(async (category) => ({ + items: category.items, + doesCategoryApply: await category.detect(changedFiles), + }))); + for (const category of possibleCategories) { + if (category.doesCategoryApply) { + for (const item of category.items) { + checks.add(item); + } } } } @@ -18508,12 +16722,11 @@ async function generateDynamicChecksAndCheckForCompletion() { // Put the PR body back together, need to add the markers back in const newBody = contentBeforeChecklist + checklistStartsWith + checklist + checklistEndsWith + contentAfterChecklist; // Update the PR body - if (didChecklistChange) { + if (didChecklistChange && prNumber !== undefined) { console.log('Checklist changed, updating PR...'); await GithubUtils_1.default.octokit.pulls.update({ owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, - // eslint-disable-next-line @typescript-eslint/naming-convention pull_number: prNumber, body: newBody, }); @@ -18558,7 +16771,7 @@ const github_1 = __importDefault(__nccwpck_require__(5438)); const parser_1 = __nccwpck_require__(5026); const traverse_1 = __importDefault(__nccwpck_require__(1380)); const CONST_1 = __importDefault(__nccwpck_require__(4097)); -const GithubUtils_1 = __importDefault(__nccwpck_require__(7999)); +const GithubUtils_1 = __importDefault(__nccwpck_require__(9296)); const promiseSome_1 = __importDefault(__nccwpck_require__(8534)); const items = [ "I verified that similar component doesn't exist in the codebase", @@ -18625,7 +16838,7 @@ async function detectReactComponentInFile(filename) { }; try { const { data } = await GithubUtils_1.default.octokit.repos.getContent(params); - const content = 'content' in data ? nodeBase64ToUtf8(data.content || '') : data; + const content = nodeBase64ToUtf8('content' in data ? data?.content ?? '' : ''); return detectReactComponent(content, filename); } catch (error) { @@ -18649,6 +16862,459 @@ const newComponentCategory = { exports["default"] = newComponentCategory; +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); + } + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); + } + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); + } + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); + } +} +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; + + /***/ }), /***/ 8534: @@ -18680,6 +17346,39 @@ function promiseSome(promises, callbackFn) { exports["default"] = promiseSome; +/***/ }), + +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; +} +exports.isEmptyObject = isEmptyObject; + + +/***/ }), + +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); +} +exports["default"] = arrayDifference; + + /***/ }), /***/ 2877: @@ -53238,7 +51937,7 @@ var _utils = __nccwpck_require__(4106); /***/ }), -/***/ 874: +/***/ 9792: /***/ ((__unused_webpack_module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; @@ -53812,7 +52511,7 @@ Object.defineProperty(exports, "VISITOR_KEYS", ({ })); var _toFastProperties = __nccwpck_require__(9049); __nccwpck_require__(1268); -__nccwpck_require__(874); +__nccwpck_require__(9792); __nccwpck_require__(1626); __nccwpck_require__(593); __nccwpck_require__(4455); @@ -59492,2189 +58191,6 @@ function validateChild(node, key, val) { //# sourceMappingURL=validate.js.map -/***/ }), - -/***/ 6717: -/***/ ((__unused_webpack_module, exports) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -// Current version. -var VERSION = '1.13.6'; - -// Establish the root object, `window` (`self`) in the browser, `global` -// on the server, or `this` in some virtual machines. We use `self` -// instead of `window` for `WebWorker` support. -var root = (typeof self == 'object' && self.self === self && self) || - (typeof global == 'object' && global.global === global && global) || - Function('return this')() || - {}; - -// Save bytes in the minified (but not gzipped) version: -var ArrayProto = Array.prototype, ObjProto = Object.prototype; -var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - -// Create quick reference variables for speed access to core prototypes. -var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - -// Modern feature detection. -var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', - supportsDataView = typeof DataView !== 'undefined'; - -// All **ECMAScript 5+** native function implementations that we hope to use -// are declared here. -var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create, - nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; - -// Create references to these builtin functions because we override them. -var _isNaN = isNaN, - _isFinite = isFinite; - -// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. -var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); -var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - -// The largest integer that can be represented exactly. -var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - -// Some functions take a variable number of arguments, or a few expected -// arguments at the beginning and then a variable number of values to operate -// on. This helper accumulates all remaining arguments past the function’s -// argument length (or an explicit `startIndex`), into an array that becomes -// the last argument. Similar to ES6’s "rest parameter". -function restArguments(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; -} - -// Is a given variable an object? -function isObject(obj) { - var type = typeof obj; - return type === 'function' || (type === 'object' && !!obj); -} - -// Is a given value equal to null? -function isNull(obj) { - return obj === null; -} - -// Is a given variable undefined? -function isUndefined(obj) { - return obj === void 0; -} - -// Is a given value a boolean? -function isBoolean(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; -} - -// Is a given value a DOM element? -function isElement(obj) { - return !!(obj && obj.nodeType === 1); -} - -// Internal function for creating a `toString`-based type tester. -function tagTester(name) { - var tag = '[object ' + name + ']'; - return function(obj) { - return toString.call(obj) === tag; - }; -} - -var isString = tagTester('String'); - -var isNumber = tagTester('Number'); - -var isDate = tagTester('Date'); - -var isRegExp = tagTester('RegExp'); - -var isError = tagTester('Error'); - -var isSymbol = tagTester('Symbol'); - -var isArrayBuffer = tagTester('ArrayBuffer'); - -var isFunction = tagTester('Function'); - -// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old -// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). -var nodelist = root.document && root.document.childNodes; -if ( true && typeof Int8Array != 'object' && typeof nodelist != 'function') { - isFunction = function(obj) { - return typeof obj == 'function' || false; - }; -} - -var isFunction$1 = isFunction; - -var hasObjectTag = tagTester('Object'); - -// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. -// In IE 11, the most common among them, this problem also applies to -// `Map`, `WeakMap` and `Set`. -var hasStringTagBug = ( - supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) - ), - isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); - -var isDataView = tagTester('DataView'); - -// In IE 10 - Edge 13, we need a different heuristic -// to determine whether an object is a `DataView`. -function ie10IsDataView(obj) { - return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); -} - -var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); - -// Is a given value an array? -// Delegates to ECMA5's native `Array.isArray`. -var isArray = nativeIsArray || tagTester('Array'); - -// Internal function to check whether `key` is an own property name of `obj`. -function has$1(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); -} - -var isArguments = tagTester('Arguments'); - -// Define a fallback version of the method in browsers (ahem, IE < 9), where -// there isn't any inspectable "Arguments" type. -(function() { - if (!isArguments(arguments)) { - isArguments = function(obj) { - return has$1(obj, 'callee'); - }; - } -}()); - -var isArguments$1 = isArguments; - -// Is a given object a finite number? -function isFinite$1(obj) { - return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); -} - -// Is the given value `NaN`? -function isNaN$1(obj) { - return isNumber(obj) && _isNaN(obj); -} - -// Predicate-generating function. Often useful outside of Underscore. -function constant(value) { - return function() { - return value; - }; -} - -// Common internal logic for `isArrayLike` and `isBufferLike`. -function createSizePropertyCheck(getSizeProperty) { - return function(collection) { - var sizeProperty = getSizeProperty(collection); - return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; - } -} - -// Internal helper to generate a function to obtain property `key` from `obj`. -function shallowProperty(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; -} - -// Internal helper to obtain the `byteLength` property of an object. -var getByteLength = shallowProperty('byteLength'); - -// Internal helper to determine whether we should spend extensive checks against -// `ArrayBuffer` et al. -var isBufferLike = createSizePropertyCheck(getByteLength); - -// Is a given value a typed array? -var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; -function isTypedArray(obj) { - // `ArrayBuffer.isView` is the most future-proof, so use it when available. - // Otherwise, fall back on the above regular expression. - return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : - isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); -} - -var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); - -// Internal helper to obtain the `length` property of an object. -var getLength = shallowProperty('length'); - -// Internal helper to create a simple lookup structure. -// `collectNonEnumProps` used to depend on `_.contains`, but this led to -// circular imports. `emulatedSet` is a one-off solution that only works for -// arrays of strings. -function emulatedSet(keys) { - var hash = {}; - for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; - return { - contains: function(key) { return hash[key] === true; }, - push: function(key) { - hash[key] = true; - return keys.push(key); - } - }; -} - -// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't -// be iterated by `for key in ...` and thus missed. Extends `keys` in place if -// needed. -function collectNonEnumProps(obj, keys) { - keys = emulatedSet(keys); - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto; - - // Constructor is a special case. - var prop = 'constructor'; - if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); - - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { - keys.push(prop); - } - } -} - -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native `Object.keys`. -function keys(obj) { - if (!isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has$1(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -function isEmpty(obj) { - if (obj == null) return true; - // Skip the more expensive `toString`-based type checks if `obj` has no - // `.length`. - var length = getLength(obj); - if (typeof length == 'number' && ( - isArray(obj) || isString(obj) || isArguments$1(obj) - )) return length === 0; - return getLength(keys(obj)) === 0; -} - -// Returns whether an object has a given set of `key:value` pairs. -function isMatch(object, attrs) { - var _keys = keys(attrs), length = _keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = _keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; -} - -// If Underscore is called as a function, it returns a wrapped object that can -// be used OO-style. This wrapper holds altered versions of all functions added -// through `_.mixin`. Wrapped objects may be chained. -function _$1(obj) { - if (obj instanceof _$1) return obj; - if (!(this instanceof _$1)) return new _$1(obj); - this._wrapped = obj; -} - -_$1.VERSION = VERSION; - -// Extracts the result from a wrapped and chained object. -_$1.prototype.value = function() { - return this._wrapped; -}; - -// Provide unwrapping proxies for some methods used in engine operations -// such as arithmetic and JSON stringification. -_$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; - -_$1.prototype.toString = function() { - return String(this._wrapped); -}; - -// Internal function to wrap or shallow-copy an ArrayBuffer, -// typed array or DataView to a new view, reusing the buffer. -function toBufferView(bufferSource) { - return new Uint8Array( - bufferSource.buffer || bufferSource, - bufferSource.byteOffset || 0, - getByteLength(bufferSource) - ); -} - -// We use this string twice, so give it a name for minification. -var tagDataView = '[object DataView]'; - -// Internal recursive comparison function for `_.isEqual`. -function eq(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -// Internal recursive comparison function for `_.isEqual`. -function deepEq(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _$1) a = a._wrapped; - if (b instanceof _$1) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - // Work around a bug in IE 10 - Edge 13. - if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { - if (!isDataView$1(b)) return false; - className = tagDataView; - } - switch (className) { - // These types are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - case '[object ArrayBuffer]': - case tagDataView: - // Coerce to typed array so we can fall through. - return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); - } - - var areArrays = className === '[object Array]'; - if (!areArrays && isTypedArray$1(a)) { - var byteLength = getByteLength(a); - if (byteLength !== getByteLength(b)) return false; - if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; - areArrays = true; - } - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && - isFunction$1(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var _keys = keys(a), key; - length = _keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = _keys[length]; - if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -// Perform a deep comparison to check if two objects are equal. -function isEqual(a, b) { - return eq(a, b); -} - -// Retrieve all the enumerable property names of an object. -function allKeys(obj) { - if (!isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Since the regular `Object.prototype.toString` type tests don't work for -// some types in IE 11, we use a fingerprinting heuristic instead, based -// on the methods. It's not great, but it's the best we got. -// The fingerprint method lists are defined below. -function ie11fingerprint(methods) { - var length = getLength(methods); - return function(obj) { - if (obj == null) return false; - // `Map`, `WeakMap` and `Set` have no enumerable keys. - var keys = allKeys(obj); - if (getLength(keys)) return false; - for (var i = 0; i < length; i++) { - if (!isFunction$1(obj[methods[i]])) return false; - } - // If we are testing against `WeakMap`, we need to ensure that - // `obj` doesn't have a `forEach` method in order to distinguish - // it from a regular `Map`. - return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); - }; -} - -// In the interest of compact minification, we write -// each string in the fingerprints only once. -var forEachName = 'forEach', - hasName = 'has', - commonInit = ['clear', 'delete'], - mapTail = ['get', hasName, 'set']; - -// `Map`, `WeakMap` and `Set` each have slightly different -// combinations of the above sublists. -var mapMethods = commonInit.concat(forEachName, mapTail), - weakMapMethods = commonInit.concat(mapTail), - setMethods = ['add'].concat(commonInit, forEachName, hasName); - -var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); - -var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); - -var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); - -var isWeakSet = tagTester('WeakSet'); - -// Retrieve the values of an object's properties. -function values(obj) { - var _keys = keys(obj); - var length = _keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[_keys[i]]; - } - return values; -} - -// Convert an object into a list of `[key, value]` pairs. -// The opposite of `_.object` with one argument. -function pairs(obj) { - var _keys = keys(obj); - var length = _keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [_keys[i], obj[_keys[i]]]; - } - return pairs; -} - -// Invert the keys and values of an object. The values must be serializable. -function invert(obj) { - var result = {}; - var _keys = keys(obj); - for (var i = 0, length = _keys.length; i < length; i++) { - result[obj[_keys[i]]] = _keys[i]; - } - return result; -} - -// Return a sorted list of the function names available on the object. -function functions(obj) { - var names = []; - for (var key in obj) { - if (isFunction$1(obj[key])) names.push(key); - } - return names.sort(); -} - -// An internal function for creating assigner functions. -function createAssigner(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } - } - return obj; - }; -} - -// Extend a given object with all the properties in passed-in object(s). -var extend = createAssigner(allKeys); - -// Assigns a given object with all the own properties in the passed-in -// object(s). -// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) -var extendOwn = createAssigner(keys); - -// Fill in a given object with default properties. -var defaults = createAssigner(allKeys, true); - -// Create a naked function reference for surrogate-prototype-swapping. -function ctor() { - return function(){}; -} - -// An internal function for creating a new object that inherits from another. -function baseCreate(prototype) { - if (!isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - var Ctor = ctor(); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; -} - -// Creates an object that inherits from the given prototype object. -// If additional properties are provided then they will be added to the -// created object. -function create(prototype, props) { - var result = baseCreate(prototype); - if (props) extendOwn(result, props); - return result; -} - -// Create a (shallow-cloned) duplicate of an object. -function clone(obj) { - if (!isObject(obj)) return obj; - return isArray(obj) ? obj.slice() : extend({}, obj); -} - -// Invokes `interceptor` with the `obj` and then returns `obj`. -// The primary purpose of this method is to "tap into" a method chain, in -// order to perform operations on intermediate results within the chain. -function tap(obj, interceptor) { - interceptor(obj); - return obj; -} - -// Normalize a (deep) property `path` to array. -// Like `_.iteratee`, this function can be customized. -function toPath$1(path) { - return isArray(path) ? path : [path]; -} -_$1.toPath = toPath$1; - -// Internal wrapper for `_.toPath` to enable minification. -// Similar to `cb` for `_.iteratee`. -function toPath(path) { - return _$1.toPath(path); -} - -// Internal function to obtain a nested property in `obj` along `path`. -function deepGet(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; -} - -// Get the value of the (deep) property on `path` from `object`. -// If any property in `path` does not exist or if the value is -// `undefined`, return `defaultValue` instead. -// The `path` is normalized through `_.toPath`. -function get(object, path, defaultValue) { - var value = deepGet(object, toPath(path)); - return isUndefined(value) ? defaultValue : value; -} - -// Shortcut function for checking if an object has a given property directly on -// itself (in other words, not on a prototype). Unlike the internal `has` -// function, this public version can also traverse nested properties. -function has(obj, path) { - path = toPath(path); - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (!has$1(obj, key)) return false; - obj = obj[key]; - } - return !!length; -} - -// Keep the identity function around for default iteratees. -function identity(value) { - return value; -} - -// Returns a predicate for checking whether an object has a given set of -// `key:value` pairs. -function matcher(attrs) { - attrs = extendOwn({}, attrs); - return function(obj) { - return isMatch(obj, attrs); - }; -} - -// Creates a function that, when passed an object, will traverse that object’s -// properties down the given `path`, specified as an array of keys or indices. -function property(path) { - path = toPath(path); - return function(obj) { - return deepGet(obj, path); - }; -} - -// Internal function that returns an efficient (for current engines) version -// of the passed-in callback, to be repeatedly applied in other Underscore -// functions. -function optimizeCb(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; -} - -// An internal function to generate callbacks that can be applied to each -// element in a collection, returning the desired result — either `_.identity`, -// an arbitrary callback, a property matcher, or a property accessor. -function baseIteratee(value, context, argCount) { - if (value == null) return identity; - if (isFunction$1(value)) return optimizeCb(value, context, argCount); - if (isObject(value) && !isArray(value)) return matcher(value); - return property(value); -} - -// External wrapper for our callback generator. Users may customize -// `_.iteratee` if they want additional predicate/iteratee shorthand styles. -// This abstraction hides the internal-only `argCount` argument. -function iteratee(value, context) { - return baseIteratee(value, context, Infinity); -} -_$1.iteratee = iteratee; - -// The function we call internally to generate a callback. It invokes -// `_.iteratee` if overridden, otherwise `baseIteratee`. -function cb(value, context, argCount) { - if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); - return baseIteratee(value, context, argCount); -} - -// Returns the results of applying the `iteratee` to each element of `obj`. -// In contrast to `_.map` it returns an object. -function mapObject(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = keys(obj), - length = _keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = _keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Predicate-generating function. Often useful outside of Underscore. -function noop(){} - -// Generates a function for a given object that returns a given property. -function propertyOf(obj) { - if (obj == null) return noop; - return function(path) { - return get(obj, path); - }; -} - -// Run a function **n** times. -function times(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; -} - -// Return a random integer between `min` and `max` (inclusive). -function random(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); -} - -// A (possibly faster) way to get the current timestamp as an integer. -var now = Date.now || function() { - return new Date().getTime(); -}; - -// Internal helper to generate functions for escaping and unescaping strings -// to/from HTML interpolation. -function createEscaper(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; -} - -// Internal list of HTML entities for escaping. -var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' -}; - -// Function for escaping strings to HTML interpolation. -var _escape = createEscaper(escapeMap); - -// Internal list of HTML entities for unescaping. -var unescapeMap = invert(escapeMap); - -// Function for unescaping strings from HTML interpolation. -var _unescape = createEscaper(unescapeMap); - -// By default, Underscore uses ERB-style template delimiters. Change the -// following template settings to use alternative delimiters. -var templateSettings = _$1.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g -}; - -// When customizing `_.templateSettings`, if you don't want to define an -// interpolation, evaluation or escaping regex, we need one that is -// guaranteed not to match. -var noMatch = /(.)^/; - -// Certain characters need to be escaped so that they can be put into a -// string literal. -var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' -}; - -var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - -function escapeChar(match) { - return '\\' + escapes[match]; -} - -// In order to prevent third-party code injection through -// `_.templateSettings.variable`, we test it against the following regular -// expression. It is intentionally a bit more liberal than just matching valid -// identifiers, but still prevents possible loopholes through defaults or -// destructuring assignment. -var bareIdentifier = /^\s*(\w|\$)+\s*$/; - -// JavaScript micro-templating, similar to John Resig's implementation. -// Underscore templating handles arbitrary delimiters, preserves whitespace, -// and correctly escapes quotes within interpolated code. -// NB: `oldSettings` only exists for backwards compatibility. -function template(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = defaults({}, settings, _$1.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - var argument = settings.variable; - if (argument) { - // Insure against third-party code injection. (CVE-2021-23358) - if (!bareIdentifier.test(argument)) throw new Error( - 'variable is not a bare identifier: ' + argument - ); - } else { - // If a variable is not specified, place data values in local scope. - source = 'with(obj||{}){\n' + source + '}\n'; - argument = 'obj'; - } - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(argument, '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _$1); - }; - - // Provide the compiled source as a convenience for precompilation. - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; -} - -// Traverses the children of `obj` along `path`. If a child is a function, it -// is invoked with its parent as context. Returns the value of the final -// child, or `fallback` if any child is undefined. -function result(obj, path, fallback) { - path = toPath(path); - var length = path.length; - if (!length) { - return isFunction$1(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. - } - obj = isFunction$1(prop) ? prop.call(obj) : prop; - } - return obj; -} - -// Generate a unique integer id (unique within the entire client session). -// Useful for temporary DOM ids. -var idCounter = 0; -function uniqueId(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; -} - -// Start chaining a wrapped Underscore object. -function chain(obj) { - var instance = _$1(obj); - instance._chain = true; - return instance; -} - -// Internal function to execute `sourceFunc` bound to `context` with optional -// `args`. Determines whether to execute a function as a constructor or as a -// normal function. -function executeBound(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (isObject(result)) return result; - return self; -} - -// Partially apply a function by creating a version that has had some of its -// arguments pre-filled, without changing its dynamic `this` context. `_` acts -// as a placeholder by default, allowing any combination of arguments to be -// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. -var partial = restArguments(function(func, boundArgs) { - var placeholder = partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; -}); - -partial.placeholder = _$1; - -// Create a function bound to a given object (assigning `this`, and arguments, -// optionally). -var bind = restArguments(function(func, context, args) { - if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; -}); - -// Internal helper for collection methods to determine whether a collection -// should be iterated as an array or as an object. -// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength -// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 -var isArrayLike = createSizePropertyCheck(getLength); - -// Internal implementation of a recursive `flatten` function. -function flatten$1(input, depth, strict, output) { - output = output || []; - if (!depth && depth !== 0) { - depth = Infinity; - } else if (depth <= 0) { - return output.concat(input); - } - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { - // Flatten current level of array or arguments object. - if (depth > 1) { - flatten$1(value, depth - 1, strict, output); - idx = output.length; - } else { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; - } - } - return output; -} - -// Bind a number of an object's methods to that object. Remaining arguments -// are the method names to be bound. Useful for ensuring that all callbacks -// defined on an object belong to it. -var bindAll = restArguments(function(obj, keys) { - keys = flatten$1(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = bind(obj[key], obj); - } - return obj; -}); - -// Memoize an expensive function by storing its results. -function memoize(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; -} - -// Delays a function for the given number of milliseconds, and then calls -// it with the arguments supplied. -var delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); -}); - -// Defers a function, scheduling it to run after the current call stack has -// cleared. -var defer = partial(delay, _$1, 1); - -// Returns a function, that, when invoked, will only be triggered at most once -// during a given window of time. Normally, the throttled function will run -// as much as it can, without ever going more than once per `wait` duration; -// but if you'd like to disable the execution on the leading edge, pass -// `{leading: false}`. To disable execution on the trailing edge, ditto. -function throttle(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var _now = now(); - if (!previous && options.leading === false) previous = _now; - var remaining = wait - (_now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = _now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); - } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; -} - -// When a sequence of calls of the returned function ends, the argument -// function is triggered. The end of a sequence is defined by the `wait` -// parameter. If `immediate` is passed, the argument function will be -// triggered at the beginning of the sequence instead of at the end. -function debounce(func, wait, immediate) { - var timeout, previous, args, result, context; - - var later = function() { - var passed = now() - previous; - if (wait > passed) { - timeout = setTimeout(later, wait - passed); - } else { - timeout = null; - if (!immediate) result = func.apply(context, args); - // This check is needed because `func` can recursively invoke `debounced`. - if (!timeout) args = context = null; - } - }; - - var debounced = restArguments(function(_args) { - context = this; - args = _args; - previous = now(); - if (!timeout) { - timeout = setTimeout(later, wait); - if (immediate) result = func.apply(context, args); - } - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = args = context = null; - }; - - return debounced; -} - -// Returns the first function passed as an argument to the second, -// allowing you to adjust arguments, run code before and after, and -// conditionally execute the original function. -function wrap(func, wrapper) { - return partial(wrapper, func); -} - -// Returns a negated version of the passed-in predicate. -function negate(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} - -// Returns a function that is the composition of a list of functions, each -// consuming the return value of the function that follows. -function compose() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; -} - -// Returns a function that will only be executed on and after the Nth call. -function after(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; -} - -// Returns a function that will only be executed up to (but not including) the -// Nth call. -function before(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); - } - if (times <= 1) func = null; - return memo; - }; -} - -// Returns a function that will be executed at most one time, no matter how -// often you call it. Useful for lazy initialization. -var once = partial(before, 2); - -// Returns the first key on an object that passes a truth test. -function findKey(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = keys(obj), key; - for (var i = 0, length = _keys.length; i < length; i++) { - key = _keys[i]; - if (predicate(obj[key], key, obj)) return key; - } -} - -// Internal function to generate `_.findIndex` and `_.findLastIndex`. -function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; - } - return -1; - }; -} - -// Returns the first index on an array-like that passes a truth test. -var findIndex = createPredicateIndexFinder(1); - -// Returns the last index on an array-like that passes a truth test. -var findLastIndex = createPredicateIndexFinder(-1); - -// Use a comparator function to figure out the smallest index at which -// an object should be inserted so as to maintain order. Uses binary search. -function sortedIndex(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; -} - -// Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. -function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; - } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), isNaN$1); - return idx >= 0 ? idx + i : -1; - } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; - } - return -1; - }; -} - -// Return the position of the first occurrence of an item in an array, -// or -1 if the item is not included in the array. -// If the array is large and already in sort order, pass `true` -// for **isSorted** to use binary search. -var indexOf = createIndexFinder(1, findIndex, sortedIndex); - -// Return the position of the last occurrence of an item in an array, -// or -1 if the item is not included in the array. -var lastIndexOf = createIndexFinder(-1, findLastIndex); - -// Return the first value which passes a truth test. -function find(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? findIndex : findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; -} - -// Convenience version of a common use case of `_.find`: getting the first -// object containing specific `key:value` pairs. -function findWhere(obj, attrs) { - return find(obj, matcher(attrs)); -} - -// The cornerstone for collection functions, an `each` -// implementation, aka `forEach`. -// Handles raw objects in addition to array-likes. Treats all -// sparse array-likes as if they were dense. -function each(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var _keys = keys(obj); - for (i = 0, length = _keys.length; i < length; i++) { - iteratee(obj[_keys[i]], _keys[i], obj); - } - } - return obj; -} - -// Return the results of applying the iteratee to each element. -function map(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Internal helper to create a reducing function, iterating left or right. -function createReduce(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[_keys ? _keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = _keys ? _keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; - - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; -} - -// **Reduce** builds up a single result from a list of values, aka `inject`, -// or `foldl`. -var reduce = createReduce(1); - -// The right-associative version of reduce, also known as `foldr`. -var reduceRight = createReduce(-1); - -// Return all the elements that pass a truth test. -function filter(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; -} - -// Return all the elements for which a truth test fails. -function reject(obj, predicate, context) { - return filter(obj, negate(cb(predicate)), context); -} - -// Determine whether all of the elements pass a truth test. -function every(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; -} - -// Determine if at least one element in the object passes a truth test. -function some(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; -} - -// Determine if the array or object contains a given item (using `===`). -function contains(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return indexOf(obj, item, fromIndex) >= 0; -} - -// Invoke a method (with arguments) on every item in a collection. -var invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (isFunction$1(path)) { - func = path; - } else { - path = toPath(path); - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); -}); - -// Convenience version of a common use case of `_.map`: fetching a property. -function pluck(obj, key) { - return map(obj, property(key)); -} - -// Convenience version of a common use case of `_.filter`: selecting only -// objects containing specific `key:value` pairs. -function where(obj, attrs) { - return filter(obj, matcher(attrs)); -} - -// Return the maximum element (or element-based computation). -function max(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} - -// Return the minimum element (or element-based computation). -function min(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || (computed === Infinity && result === Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} - -// Safely create a real, live array from anything iterable. -var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; -function toArray(obj) { - if (!obj) return []; - if (isArray(obj)) return slice.call(obj); - if (isString(obj)) { - // Keep surrogate pair characters together. - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return map(obj, identity); - return values(obj); -} - -// Sample **n** random values from a collection using the modern version of the -// [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). -// If **n** is not specified, returns a single random element. -// The internal `guard` argument allows it to work with `_.map`. -function sample(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = values(obj); - return obj[random(obj.length - 1)]; - } - var sample = toArray(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); -} - -// Shuffle a collection. -function shuffle(obj) { - return sample(obj, Infinity); -} - -// Sort the object's values by a criterion produced by an iteratee. -function sortBy(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return pluck(map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); -} - -// An internal function used for aggregate "group by" operations. -function group(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; -} - -// Groups the object's values by a criterion. Pass either a string attribute -// to group by, or a function that returns the criterion. -var groupBy = group(function(result, value, key) { - if (has$1(result, key)) result[key].push(value); else result[key] = [value]; -}); - -// Indexes the object's values by a criterion, similar to `_.groupBy`, but for -// when you know that your index values will be unique. -var indexBy = group(function(result, value, key) { - result[key] = value; -}); - -// Counts instances of an object that group by a certain criterion. Pass -// either a string attribute to count by, or a function that returns the -// criterion. -var countBy = group(function(result, value, key) { - if (has$1(result, key)) result[key]++; else result[key] = 1; -}); - -// Split a collection into two arrays: one whose elements all pass the given -// truth test, and one whose elements all do not pass the truth test. -var partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); -}, true); - -// Return the number of elements in a collection. -function size(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : keys(obj).length; -} - -// Internal `_.pick` helper function to determine whether `key` is an enumerable -// property name of `obj`. -function keyInObj(value, key, obj) { - return key in obj; -} - -// Return a copy of the object only containing the allowed properties. -var pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (isFunction$1(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten$1(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; -}); - -// Return a copy of the object without the disallowed properties. -var omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (isFunction$1(iteratee)) { - iteratee = negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = map(flatten$1(keys, false, false), String); - iteratee = function(value, key) { - return !contains(keys, key); - }; - } - return pick(obj, iteratee, context); -}); - -// Returns everything but the last entry of the array. Especially useful on -// the arguments object. Passing **n** will return all the values in -// the array, excluding the last N. -function initial(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); -} - -// Get the first element of an array. Passing **n** will return the first N -// values in the array. The **guard** check allows it to work with `_.map`. -function first(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[0]; - return initial(array, array.length - n); -} - -// Returns everything but the first entry of the `array`. Especially useful on -// the `arguments` object. Passing an **n** will return the rest N values in the -// `array`. -function rest(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); -} - -// Get the last element of an array. Passing **n** will return the last N -// values in the array. -function last(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return rest(array, Math.max(0, array.length - n)); -} - -// Trim out all falsy values from an array. -function compact(array) { - return filter(array, Boolean); -} - -// Flatten out an array, either recursively (by default), or up to `depth`. -// Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. -function flatten(array, depth) { - return flatten$1(array, depth, false); -} - -// Take the difference between one array and a number of other arrays. -// Only the elements present in just the first array will remain. -var difference = restArguments(function(array, rest) { - rest = flatten$1(rest, true, true); - return filter(array, function(value){ - return !contains(rest, value); - }); -}); - -// Return a version of the array that does not contain the specified value(s). -var without = restArguments(function(array, otherArrays) { - return difference(array, otherArrays); -}); - -// Produce a duplicate-free version of the array. If the array has already -// been sorted, you have the option of using a faster algorithm. -// The faster algorithm will not work with an iteratee if the iteratee -// is not a one-to-one function, so providing an iteratee will disable -// the faster algorithm. -function uniq(array, isSorted, iteratee, context) { - if (!isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!contains(result, value)) { - result.push(value); - } - } - return result; -} - -// Produce an array that contains the union: each distinct element from all of -// the passed-in arrays. -var union = restArguments(function(arrays) { - return uniq(flatten$1(arrays, true, true)); -}); - -// Produce an array that contains every item shared between all the -// passed-in arrays. -function intersection(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; -} - -// Complement of zip. Unzip accepts an array of arrays and groups -// each array's elements on shared indices. -function unzip(array) { - var length = (array && max(array, getLength).length) || 0; - var result = Array(length); - - for (var index = 0; index < length; index++) { - result[index] = pluck(array, index); - } - return result; -} - -// Zip together multiple lists into a single array -- elements that share -// an index go together. -var zip = restArguments(unzip); - -// Converts lists into objects. Pass either a single array of `[key, value]` -// pairs, or two parallel arrays of the same length -- one of keys, and one of -// the corresponding values. Passing by pairs is the reverse of `_.pairs`. -function object(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; -} - -// Generate an integer Array containing an arithmetic progression. A port of -// the native Python `range()` function. See -// [the Python documentation](https://docs.python.org/library/functions.html#range). -function range(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } - - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); - - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } - - return range; -} - -// Chunk a single array into multiple arrays, each containing `count` or fewer -// items. -function chunk(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; -} - -// Helper function to continue chaining intermediate results. -function chainResult(instance, obj) { - return instance._chain ? _$1(obj).chain() : obj; -} - -// Add your own custom functions to the Underscore object. -function mixin(obj) { - each(functions(obj), function(name) { - var func = _$1[name] = obj[name]; - _$1.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_$1, args)); - }; - }); - return _$1; -} - -// Add all mutator `Array` functions to the wrapper. -each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) { - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) { - delete obj[0]; - } - } - return chainResult(this, obj); - }; -}); - -// Add all accessor `Array` functions to the wrapper. -each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) obj = method.apply(obj, arguments); - return chainResult(this, obj); - }; -}); - -// Named Exports - -var allExports = { - __proto__: null, - VERSION: VERSION, - restArguments: restArguments, - isObject: isObject, - isNull: isNull, - isUndefined: isUndefined, - isBoolean: isBoolean, - isElement: isElement, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isRegExp: isRegExp, - isError: isError, - isSymbol: isSymbol, - isArrayBuffer: isArrayBuffer, - isDataView: isDataView$1, - isArray: isArray, - isFunction: isFunction$1, - isArguments: isArguments$1, - isFinite: isFinite$1, - isNaN: isNaN$1, - isTypedArray: isTypedArray$1, - isEmpty: isEmpty, - isMatch: isMatch, - isEqual: isEqual, - isMap: isMap, - isWeakMap: isWeakMap, - isSet: isSet, - isWeakSet: isWeakSet, - keys: keys, - allKeys: allKeys, - values: values, - pairs: pairs, - invert: invert, - functions: functions, - methods: functions, - extend: extend, - extendOwn: extendOwn, - assign: extendOwn, - defaults: defaults, - create: create, - clone: clone, - tap: tap, - get: get, - has: has, - mapObject: mapObject, - identity: identity, - constant: constant, - noop: noop, - toPath: toPath$1, - property: property, - propertyOf: propertyOf, - matcher: matcher, - matches: matcher, - times: times, - random: random, - now: now, - escape: _escape, - unescape: _unescape, - templateSettings: templateSettings, - template: template, - result: result, - uniqueId: uniqueId, - chain: chain, - iteratee: iteratee, - partial: partial, - bind: bind, - bindAll: bindAll, - memoize: memoize, - delay: delay, - defer: defer, - throttle: throttle, - debounce: debounce, - wrap: wrap, - negate: negate, - compose: compose, - after: after, - before: before, - once: once, - findKey: findKey, - findIndex: findIndex, - findLastIndex: findLastIndex, - sortedIndex: sortedIndex, - indexOf: indexOf, - lastIndexOf: lastIndexOf, - find: find, - detect: find, - findWhere: findWhere, - each: each, - forEach: each, - map: map, - collect: map, - reduce: reduce, - foldl: reduce, - inject: reduce, - reduceRight: reduceRight, - foldr: reduceRight, - filter: filter, - select: filter, - reject: reject, - every: every, - all: every, - some: some, - any: some, - contains: contains, - includes: contains, - include: contains, - invoke: invoke, - pluck: pluck, - where: where, - max: max, - min: min, - shuffle: shuffle, - sample: sample, - sortBy: sortBy, - groupBy: groupBy, - indexBy: indexBy, - countBy: countBy, - partition: partition, - toArray: toArray, - size: size, - pick: pick, - omit: omit, - first: first, - head: first, - take: first, - initial: initial, - last: last, - rest: rest, - tail: rest, - drop: rest, - compact: compact, - flatten: flatten, - without: without, - uniq: uniq, - unique: uniq, - union: union, - intersection: intersection, - difference: difference, - unzip: unzip, - transpose: unzip, - zip: zip, - object: object, - range: range, - chunk: chunk, - mixin: mixin, - 'default': _$1 -}; - -// Default Export - -// Add all of the Underscore functions to the wrapper object. -var _ = mixin(allExports); -// Legacy Node.js API. -_._ = _; - -exports.VERSION = VERSION; -exports._ = _; -exports._escape = _escape; -exports._unescape = _unescape; -exports.after = after; -exports.allKeys = allKeys; -exports.before = before; -exports.bind = bind; -exports.bindAll = bindAll; -exports.chain = chain; -exports.chunk = chunk; -exports.clone = clone; -exports.compact = compact; -exports.compose = compose; -exports.constant = constant; -exports.contains = contains; -exports.countBy = countBy; -exports.create = create; -exports.debounce = debounce; -exports.defaults = defaults; -exports.defer = defer; -exports.delay = delay; -exports.difference = difference; -exports.each = each; -exports.every = every; -exports.extend = extend; -exports.extendOwn = extendOwn; -exports.filter = filter; -exports.find = find; -exports.findIndex = findIndex; -exports.findKey = findKey; -exports.findLastIndex = findLastIndex; -exports.findWhere = findWhere; -exports.first = first; -exports.flatten = flatten; -exports.functions = functions; -exports.get = get; -exports.groupBy = groupBy; -exports.has = has; -exports.identity = identity; -exports.indexBy = indexBy; -exports.indexOf = indexOf; -exports.initial = initial; -exports.intersection = intersection; -exports.invert = invert; -exports.invoke = invoke; -exports.isArguments = isArguments$1; -exports.isArray = isArray; -exports.isArrayBuffer = isArrayBuffer; -exports.isBoolean = isBoolean; -exports.isDataView = isDataView$1; -exports.isDate = isDate; -exports.isElement = isElement; -exports.isEmpty = isEmpty; -exports.isEqual = isEqual; -exports.isError = isError; -exports.isFinite = isFinite$1; -exports.isFunction = isFunction$1; -exports.isMap = isMap; -exports.isMatch = isMatch; -exports.isNaN = isNaN$1; -exports.isNull = isNull; -exports.isNumber = isNumber; -exports.isObject = isObject; -exports.isRegExp = isRegExp; -exports.isSet = isSet; -exports.isString = isString; -exports.isSymbol = isSymbol; -exports.isTypedArray = isTypedArray$1; -exports.isUndefined = isUndefined; -exports.isWeakMap = isWeakMap; -exports.isWeakSet = isWeakSet; -exports.iteratee = iteratee; -exports.keys = keys; -exports.last = last; -exports.lastIndexOf = lastIndexOf; -exports.map = map; -exports.mapObject = mapObject; -exports.matcher = matcher; -exports.max = max; -exports.memoize = memoize; -exports.min = min; -exports.mixin = mixin; -exports.negate = negate; -exports.noop = noop; -exports.now = now; -exports.object = object; -exports.omit = omit; -exports.once = once; -exports.pairs = pairs; -exports.partial = partial; -exports.partition = partition; -exports.pick = pick; -exports.pluck = pluck; -exports.property = property; -exports.propertyOf = propertyOf; -exports.random = random; -exports.range = range; -exports.reduce = reduce; -exports.reduceRight = reduceRight; -exports.reject = reject; -exports.rest = rest; -exports.restArguments = restArguments; -exports.result = result; -exports.sample = sample; -exports.shuffle = shuffle; -exports.size = size; -exports.some = some; -exports.sortBy = sortBy; -exports.sortedIndex = sortedIndex; -exports.tap = tap; -exports.template = template; -exports.templateSettings = templateSettings; -exports.throttle = throttle; -exports.times = times; -exports.toArray = toArray; -exports.toPath = toPath$1; -exports.union = union; -exports.uniq = uniq; -exports.uniqueId = uniqueId; -exports.unzip = unzip; -exports.values = values; -exports.where = where; -exports.without = without; -exports.wrap = wrap; -exports.zip = zip; -//# sourceMappingURL=underscore-node-f.cjs.map - - -/***/ }), - -/***/ 5067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -var underscoreNodeF = __nccwpck_require__(6717); - - - -module.exports = underscoreNodeF._; -//# sourceMappingURL=underscore-node.cjs.map - - /***/ }), /***/ 8487: diff --git a/.github/actions/javascript/awaitStagingDeploys/index.js b/.github/actions/javascript/awaitStagingDeploys/index.js index f042dbb38a91..66c6efd7b67f 100644 --- a/.github/actions/javascript/awaitStagingDeploys/index.js +++ b/.github/actions/javascript/awaitStagingDeploys/index.js @@ -10,7 +10,7 @@ const _ = __nccwpck_require__(5067); const CONST = __nccwpck_require__(4097); const ActionUtils = __nccwpck_require__(970); -const GitHubUtils = __nccwpck_require__(7999); +const GitHubUtils = __nccwpck_require__(9296); const {promiseDoWhile} = __nccwpck_require__(4502); function run() { @@ -140,936 +140,390 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 4502: +/***/ ((module) => { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +/** + * Simulates a while loop where the condition is determined by the result of a Promise. + * + * @param {Function} condition + * @param {Function} action + * @returns {Promise} + */ +function promiseWhile(condition, action) { + return new Promise((resolve, reject) => { + const loop = function () { + if (!condition()) { + resolve(); + } else { + Promise.resolve(action()).then(loop).catch(reject); + } + }; + loop(); + }); +} /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Simulates a do-while loop where the condition is determined by the result of a Promise. + * + * @param {Function} condition + * @param {Function} action + * @returns {Promise} */ -const POLL_RATE = 10000; +function promiseDoWhile(condition, action) { + return new Promise((resolve, reject) => { + action() + .then(() => promiseWhile(condition, action)) + .then(() => resolve()) + .catch(reject); + }); +} -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); +module.exports = { + promiseWhile, + promiseDoWhile, +}; - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } +/***/ }), - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - - /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] - */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); - } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); + if (options && options.trimWhitespace === false) { + return val; } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); - } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); } + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); } - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 4502: -/***/ ((module) => { - +exports.setOutput = setOutput; /** - * Simulates a while loop where the condition is determined by the result of a Promise. + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. * - * @param {Function} condition - * @param {Function} action - * @returns {Promise} */ -function promiseWhile(condition, action) { - return new Promise((resolve, reject) => { - const loop = function () { - if (!condition()) { - resolve(); - } else { - Promise.resolve(action()).then(loop).catch(reject); - } - }; - loop(); - }); +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); } - +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- /** - * Simulates a do-while loop where the condition is determined by the result of a Promise. - * - * @param {Function} condition - * @param {Function} action - * @returns {Promise} + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message */ -function promiseDoWhile(condition, action) { - return new Promise((resolve, reject) => { - action() - .then(() => promiseWhile(condition, action)) - .then(() => resolve()) - .catch(reject); - }); +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); } - -module.exports = { - promiseWhile, - promiseDoWhile, -}; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- /** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value + * Gets whether Actions Step Debug is on or not */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; } -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); } -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); } -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); } -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); -} -exports.getMultilineInput = getMultilineInput; -/** - * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. - * Support boolean input list: `true | True | TRUE | false | False | FALSE` . - * The return value is also in boolean type. - * ref: https://yaml.org/spec/1.2/spec.html#id2804923 - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns boolean - */ -function getBooleanInput(name, options) { - const trueValue = ['true', 'True', 'TRUE']; - const falseValue = ['false', 'False', 'FALSE']; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + - `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); -} -exports.getBooleanInput = getBooleanInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - const filePath = process.env['GITHUB_OUTPUT'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); - } - process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. - * - */ -function setCommandEcho(enabled) { - command_1.issue('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function error(message, properties = {}) { - command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.error = error; -/** - * Adds a warning issue - * @param message warning issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function warning(message, properties = {}) { - command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.warning = warning; -/** - * Adds a notice issue - * @param message notice issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function notice(message, properties = {}) { - command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); } exports.notice = notice; /** @@ -7242,4152 +6696,2542 @@ exports.isPlainObject = isPlainObject; /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +/***/ 467: +/***/ ((module, exports, __nccwpck_require__) => { - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +"use strict"; -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; -module.exports = Hash; +Object.defineProperty(exports, "__esModule", ({ value: true })); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -/***/ }), - -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), - -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); - -module.exports = Map; - - -/***/ }), - -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; +var Stream = _interopDefault(__nccwpck_require__(2781)); +var http = _interopDefault(__nccwpck_require__(3685)); +var Url = _interopDefault(__nccwpck_require__(7310)); +var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); +var https = _interopDefault(__nccwpck_require__(5687)); +var zlib = _interopDefault(__nccwpck_require__(9796)); +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js -/***/ }), +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); -var root = __nccwpck_require__(9882); +class Blob { + constructor() { + this[TYPE] = ''; -/** Built-in value references. */ -var Symbol = root.Symbol; + const blobParts = arguments[0]; + const options = arguments[1]; -module.exports = Symbol; + const buffers = []; + let size = 0; + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } -/***/ }), + this[BUFFER] = Buffer.concat(buffers); -/***/ 4356: -/***/ ((module) => { + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } } -module.exports = arrayMap; - - -/***/ }), - -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); -var eq = __nccwpck_require__(1901); +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); /** - * Gets the index at which the `key` is found in `array` of key-value pairs. + * fetch-error.js * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. + * FetchError interface for operational errors */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -module.exports = assocIndexOf; - - -/***/ }), - -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); /** - * The base implementation of `_.get` without support for default values. + * Create FetchError instance * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError */ -function baseGet(object, path) { - path = castPath(path, object); +function FetchError(message, type, systemError) { + Error.call(this, message); - var index = 0, - length = path.length; + this.message = message; + this.type = type; - while (object != null && index < length) { - object = object[toKey(path[index++])]; + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; } - return (index && index == length) ? object : undefined; -} - -module.exports = baseGet; + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); +let convert; +try { + convert = (__nccwpck_require__(2877).convert); +} catch (e) {} -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; +const INTERNALS = Symbol('Body internals'); -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; /** - * The base implementation of `getTag` without fallbacks for buggy environments. + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} - -module.exports = baseGetTag; +function Body(body) { + var _this = this; + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; -/***/ }), + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; + get bodyUsed() { + return this[INTERNALS].disturbed; + }, -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; -module.exports = baseIsNative; + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, -/***/ }), + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. + * @return Promise */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = baseToString; - - -/***/ }), - -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function consumeBody() { + var _this4 = this; -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} + this[INTERNALS].disturbed = true; -module.exports = castPath; + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + let body = this.body; -/***/ }), + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // body is blob + if (isBlob(body)) { + body = body.stream(); + } -var root = __nccwpck_require__(9882); + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -module.exports = coreJsData; + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + return new Body.Promise(function (resolve, reject) { + let resTimeout; -/***/ }), + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } -/***/ 2085: -/***/ ((module) => { + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } -module.exports = freeGlobal; + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + accumBytes += chunk.length; + accum.push(chunk); + }); -/***/ }), + body.on('end', function () { + if (abort) { + return; + } -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + clearTimeout(resTimeout); -var isKeyable = __nccwpck_require__(3308); + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} /** - * Gets the data for `map`. + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; -/***/ }), + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + // html5 + if (!res && str) { + res = / { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + // prevent decode issues when sites use incorrect encoding + // ref: https://hsivonen.fi/encoding-menu/ + if (charset === 'gb2312' || charset === 'gbk') { + charset = 'gb18030'; + } + } -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + // turn raw buffers into a single utf-8 buffer + return convert(buffer, 'UTF-8', charset).toString(); +} /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * Detect a URLSearchParams object + * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. + * @param Object obj Object to detect by type or brand + * @return String */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; +function isURLSearchParams(obj) { + // Duck-typing as a necessary condition. + if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { + return false; + } - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; + // Brand-checking and more duck-typing as optional condition. + return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; } -module.exports = getRawTag; - - -/***/ }), - -/***/ 3542: -/***/ ((module) => { - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. + * Check if `obj` is a W3C `Blob` object (which `File` inherits from) + * @param {*} obj + * @return {boolean} */ -function getValue(object, key) { - return object == null ? undefined : object[key]; +function isBlob(obj) { + return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); } -module.exports = getValue; - - -/***/ }), - -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - /** - * Removes all key-value entries from the hash. + * Clone body given Res/Req instance * - * @private - * @name clear - * @memberOf Hash + * @param Mixed instance Response or Request instance + * @return Mixed */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} - -module.exports = hashClear; - +function clone(instance) { + let p1, p2; + let body = instance.body; -/***/ }), + // don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } -/***/ 712: -/***/ ((module) => { + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof Stream && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; + return body; } -module.exports = hashDelete; - - -/***/ }), - -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - /** - * Gets the hash value for `key`. + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * This function assumes that instance.body is present. + * + * @param Mixed instance Any options.body input */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof Stream) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } } -module.exports = hashGet; - - -/***/ }), - -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - /** - * Checks if a hash value for `key` exists. + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes + * + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), - -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getTotalBytes(instance) { + const body = instance.body; -var nativeCreate = __nccwpck_require__(3041); -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} /** - * Sets the hash `key` to `value`. + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. + * @param Body instance Instance of Body + * @return Void */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -module.exports = hashSet; - - -/***/ }), +function writeToStream(dest, instance) { + const body = instance.body; -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } +} -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; +// expose Promise +Body.Promise = global.Promise; /** - * Checks if `value` is a property name and not a property path. + * headers.js * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + * Headers class offers convenient helpers */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} - -module.exports = isKey; +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; -/***/ }), +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } +} -/***/ 3308: -/***/ ((module) => { +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } +} /** - * Checks if `value` is suitable for use as unique object key. + * Find the key in the map object given a header name. + * + * Returns undefined if not found. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + * @param String name Header name + * @return String|Undefined */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; } -module.exports = isKeyable; +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + this[MAP] = Object.create(null); -/***/ }), + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } -var coreJsData = __nccwpck_require__(8380); + return; + } -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } -module.exports = isMasked; + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } -/***/ }), + return this[MAP][key].join(', '); + } -/***/ 9792: -/***/ ((module) => { + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; -module.exports = listCacheClear; + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } -/***/ }), + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } -var assocIndexOf = __nccwpck_require__(6752); + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } -/** Built-in value references. */ -var splice = arrayProto.splice; + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } } +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -module.exports = listCacheDelete; - +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); -/***/ }), +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; -var assocIndexOf = __nccwpck_require__(6752); + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); +const INTERNAL = Symbol('internal'); - return index < 0 ? undefined : data[index][1]; +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; } -module.exports = listCacheGet; +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; -/***/ }), + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNAL].index = index + 1; -var assocIndexOf = __nccwpck_require__(6752); + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); /** - * Checks if a list cache value for `key` exists. + * Export the Headers object in a form that Node.js can consume. * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param Headers headers + * @return Object */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } -var assocIndexOf = __nccwpck_require__(6752); + return obj; +} /** - * Sets the list cache `key` to `value`. + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. + * @param Object obj Object of headers + * @return Headers */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; } -module.exports = listCacheSet; - - -/***/ }), - -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$1 = Symbol('Response internals'); -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; /** - * Removes all key-value entries from the map. + * Response class * - * @private - * @name clear - * @memberOf MapCache + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Body.call(this, body, opts); -/***/ }), + const status = opts.status || 200; + const headers = new Headers(opts.headers); -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -var getMapData = __nccwpck_require__(9980); + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + get url() { + return this[INTERNALS$1].url || ''; + } -module.exports = mapCacheDelete; + get status() { + return this[INTERNALS$1].status; + } + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } -/***/ }), + get redirected() { + return this[INTERNALS$1].counter > 0; + } -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + get statusText() { + return this[INTERNALS$1].statusText; + } -var getMapData = __nccwpck_require__(9980); + get headers() { + return this[INTERNALS$1].headers; + } -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } } -module.exports = mapCacheGet; +Body.mixIn(Response.prototype); +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); -/***/ }), +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; -var getMapData = __nccwpck_require__(9980); +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; /** - * Checks if a map value for `key` exists. + * Wrapper around `new URL` to handle arbitrary URLs * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param {string} urlStr + * @return {void} */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -module.exports = mapCacheHas; - - -/***/ }), +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} -var getMapData = __nccwpck_require__(9980); +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; /** - * Sets the map `key` to `value`. + * Check if a value is an instance of Request. * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. + * @param Mixed input + * @return Boolean */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; } -module.exports = mapCacheSet; - - -/***/ }), - -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var memoize = __nccwpck_require__(9885); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * Request class * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var cache = result.cache; - return result; -} + let parsedURL; -module.exports = memoizeCapped; + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); -/***/ }), + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; -var getNative = __nccwpck_require__(4479); + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + const headers = new Headers(init.headers || input.headers || {}); -module.exports = nativeCreate; + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; -/***/ }), - -/***/ 4200: -/***/ ((module) => { - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} - -module.exports = objectToString; - - -/***/ }), + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; -var freeGlobal = __nccwpck_require__(2085); + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + get method() { + return this[INTERNALS$2].method; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } -module.exports = root; + get headers() { + return this[INTERNALS$2].headers; + } + get redirect() { + return this[INTERNALS$2].redirect; + } -/***/ }), + get signal() { + return this[INTERNALS$2].signal; + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} -var memoizeCapped = __nccwpck_require__(9422); +Body.mixIn(Request.prototype); -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); /** - * Converts `string` to a property path array. + * Convert a Request to Node.js http request options. * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. + * @param Request A Request instance + * @return Object The options object to be passed to http.request */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); -/***/ }), + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } -var isSymbol = __nccwpck_require__(6403); + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } -module.exports = toKey; + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } -/***/ }), + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } -/***/ 6928: -/***/ ((module) => { + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} /** - * Converts `func` to its source code. + * abort-error.js * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. + * AbortError interface for cancelled requests */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -module.exports = toSource; - - -/***/ }), - -/***/ 1901: -/***/ ((module) => { /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false + * Create AbortError instance * - * _.eq(NaN, NaN); - * // => true + * @param String message Error message for human + * @return AbortError */ -function eq(value, other) { - return value === other || (value !== value && other !== other); +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); } -module.exports = eq; +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; +const URL$1 = Url.URL || whatwgUrl.URL; -/***/ }), +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; -var baseGet = __nccwpck_require__(5758); + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 + * Fetch function * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} +function fetch(url, opts) { -module.exports = get; + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + Body.Promise = fetch.Promise; -/***/ }), + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); -/***/ 4869: -/***/ ((module) => { + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + let response = null; -module.exports = isArray; + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + request.body.destroy(error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + if (signal && signal.aborted) { + abort(); + return; + } -/***/ }), + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // send request + const req = send(options); + let reqTimeout; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -module.exports = isFunction; + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + finalize(); + }); -/***/ }), + req.on('response', function (res) { + clearTimeout(reqTimeout); -/***/ 3334: -/***/ ((module) => { + const headers = createHeadersLenient(res.headers); -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); -module.exports = isObject; + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } -/***/ }), + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } -/***/ 5926: -/***/ ((module) => { + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} + if (!isDomainOrSubdomain(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } -module.exports = isObjectLike; + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } -/***/ }), + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} + // HTTP-network fetch step 12.1.1.4: handle content codings -module.exports = isSymbol; + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; -/***/ }), + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + return; + } -var MapCache = __nccwpck_require__(938); + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + writeToStream(req, request); + }); +} /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] + * Redirect code matching * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * @param Number code Status code + * @return Boolean */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; -// Expose `MapCache`. -memoize.Cache = MapCache; +// expose Promise +fetch.Promise = global.Promise; -module.exports = memoize; +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports["default"] = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; /***/ }), -/***/ 2931: +/***/ 2299: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var baseToString = __nccwpck_require__(6792); +"use strict"; -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); -} -module.exports = toString; +var punycode = __nccwpck_require__(5477); +var mappingTable = __nccwpck_require__(1907); +var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 +}; -/***/ }), +function normalize(str) { // fix bug in v8 + return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); +} -/***/ 467: -/***/ ((module, exports, __nccwpck_require__) => { +function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; -"use strict"; + while (start <= end) { + var mid = Math.floor((start + end) / 2); + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + return null; +} -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } +var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; -var Stream = _interopDefault(__nccwpck_require__(2781)); -var http = _interopDefault(__nccwpck_require__(3685)); -var Url = _interopDefault(__nccwpck_require__(7310)); -var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); -var https = _interopDefault(__nccwpck_require__(5687)); -var zlib = _interopDefault(__nccwpck_require__(9796)); +function countSymbols(string) { + return string + // replace every surrogate pair with a BMP symbol + .replace(regexAstralSymbols, '_') + // then get the length + .length; +} -// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js +function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; -// fix for "Readable" isn't a named export issue -const Readable = Stream.Readable; + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); -const BUFFER = Symbol('buffer'); -const TYPE = Symbol('type'); + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } -class Blob { - constructor() { - this[TYPE] = ''; + processed += String.fromCodePoint(codePoint); + break; + } + } - const blobParts = arguments[0]; - const options = arguments[1]; + return { + string: processed, + error: hasError + }; +} - const buffers = []; - let size = 0; +var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; - if (blobParts) { - const a = blobParts; - const length = Number(a.length); - for (let i = 0; i < length; i++) { - const element = a[i]; - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = element[BUFFER]; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); - } - size += buffer.length; - buffers.push(buffer); - } - } +function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } - this[BUFFER] = Buffer.concat(buffers); + var error = false; - let type = options && options.type !== undefined && String(options.type).toLowerCase(); - if (type && !/[^\u0020-\u007E]/.test(type)) { - this[TYPE] = type; - } - } - get size() { - return this[BUFFER].length; - } - get type() { - return this[TYPE]; - } - text() { - return Promise.resolve(this[BUFFER].toString()); - } - arrayBuffer() { - const buf = this[BUFFER]; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); - } - stream() { - const readable = new Readable(); - readable._read = function () {}; - readable.push(this[BUFFER]); - readable.push(null); - return readable; - } - toString() { - return '[object Blob]'; - } - slice() { - const size = this.size; + if (normalize(label) !== label || + (label[3] === "-" && label[4] === "-") || + label[0] === "-" || label[label.length - 1] === "-" || + label.indexOf(".") !== -1 || + label.search(combiningMarksRegex) === 0) { + error = true; + } - const start = arguments[0]; - const end = arguments[1]; - let relativeStart, relativeEnd; - if (start === undefined) { - relativeStart = 0; - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); - } else { - relativeStart = Math.min(start, size); - } - if (end === undefined) { - relativeEnd = size; - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); - } else { - relativeEnd = Math.min(end, size); - } - const span = Math.max(relativeEnd - relativeStart, 0); + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || + (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && + status[1] !== "valid" && status[1] !== "deviation")) { + error = true; + break; + } + } - const buffer = this[BUFFER]; - const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); - const blob = new Blob([], { type: arguments[2] }); - blob[BUFFER] = slicedBuffer; - return blob; - } + return { + label: label, + error: error + }; } -Object.defineProperties(Blob.prototype, { - size: { enumerable: true }, - type: { enumerable: true }, - slice: { enumerable: true } -}); - -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); - -/** - * fetch-error.js - * - * FetchError interface for operational errors - */ - -/** - * Create FetchError instance - * - * @param String message Error message for human - * @param String type Error type for machine - * @param String systemError For Node.js system error - * @return FetchError - */ -function FetchError(message, type, systemError) { - Error.call(this, message); - - this.message = message; - this.type = type; +function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); - // when err.type is `system`, err.code contains system error code - if (systemError) { - this.code = this.errno = systemError.code; + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch(e) { + result.error = true; + } } - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); + return { + string: labels.join("."), + error: result.error + }; } -FetchError.prototype = Object.create(Error.prototype); -FetchError.prototype.constructor = FetchError; -FetchError.prototype.name = 'FetchError'; +module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch(e) { + result.error = true; + return l; + } + }); -let convert; -try { - convert = (__nccwpck_require__(2877).convert); -} catch (e) {} + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } -const INTERNALS = Symbol('Body internals'); + for (var i=0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } -// fix an issue where "PassThrough" isn't a named export for node <10 -const PassThrough = Stream.PassThrough; + if (result.error) return null; + return labels.join("."); +}; -/** - * Body mixin - * - * Ref: https://fetch.spec.whatwg.org/#body - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -function Body(body) { - var _this = this; +module.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref$size = _ref.size; + return { + domain: result.string, + error: result.error + }; +}; - let size = _ref$size === undefined ? 0 : _ref$size; - var _ref$timeout = _ref.timeout; - let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; +module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - if (body == null) { - // body is undefined or null - body = null; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - body = Buffer.from(body.toString()); - } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - body = Buffer.from(body); - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); - } else if (body instanceof Stream) ; else { - // none of the above - // coerce to string then buffer - body = Buffer.from(String(body)); - } - this[INTERNALS] = { - body, - disturbed: false, - error: null - }; - this.size = size; - this.timeout = timeout; - if (body instanceof Stream) { - body.on('error', function (err) { - const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); - _this[INTERNALS].error = error; - }); - } -} +/***/ }), -Body.prototype = { - get body() { - return this[INTERNALS].body; - }, +/***/ 5871: +/***/ ((module) => { - get bodyUsed() { - return this[INTERNALS].disturbed; - }, +"use strict"; - /** - * Decode response as ArrayBuffer - * - * @return Promise - */ - arrayBuffer() { - return consumeBody.call(this).then(function (buf) { - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - }); - }, - /** - * Return raw response as Blob - * - * @return Promise - */ - blob() { - let ct = this.headers && this.headers.get('content-type') || ''; - return consumeBody.call(this).then(function (buf) { - return Object.assign( - // Prevent copying - new Blob([], { - type: ct.toLowerCase() - }), { - [BUFFER]: buf - }); - }); - }, +var conversions = {}; +module.exports = conversions; - /** - * Decode response as json - * - * @return Promise - */ - json() { - var _this2 = this; +function sign(x) { + return x < 0 ? -1 : 1; +} - return consumeBody.call(this).then(function (buffer) { - try { - return JSON.parse(buffer.toString()); - } catch (err) { - return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); - } - }); - }, +function evenRound(x) { + // Round x to the nearest integer, choosing the even integer if it lies halfway between two. + if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) + return Math.floor(x); + } else { + return Math.round(x); + } +} - /** - * Decode response as text - * - * @return Promise - */ - text() { - return consumeBody.call(this).then(function (buffer) { - return buffer.toString(); - }); - }, +function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength; + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); + const upperBound = Math.pow(2, bitLength) - 1; - /** - * Decode response as buffer (non-spec api) - * - * @return Promise - */ - buffer() { - return consumeBody.call(this); - }, + const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); + const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - /** - * Decode response as text, while automatically detecting the encoding and - * trying to decode to UTF-8 (non-spec api) - * - * @return Promise - */ - textConverted() { - var _this3 = this; + return function(V, opts) { + if (!opts) opts = {}; - return consumeBody.call(this).then(function (buffer) { - return convertBody(buffer, _this3.headers); - }); - } -}; + let x = +V; -// In browsers, all properties are enumerable. -Object.defineProperties(Body.prototype, { - body: { enumerable: true }, - bodyUsed: { enumerable: true }, - arrayBuffer: { enumerable: true }, - blob: { enumerable: true }, - json: { enumerable: true }, - text: { enumerable: true } -}); + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite number"); + } -Body.mixIn = function (proto) { - for (const name of Object.getOwnPropertyNames(Body.prototype)) { - // istanbul ignore else: future proof - if (!(name in proto)) { - const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); - Object.defineProperty(proto, name, desc); - } - } -}; + x = sign(x) * Math.floor(Math.abs(x)); + if (x < lowerBound || x > upperBound) { + throw new TypeError("Argument is not in byte range"); + } -/** - * Consume and convert an entire Body to a Buffer. - * - * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body - * - * @return Promise - */ -function consumeBody() { - var _this4 = this; + return x; + } - if (this[INTERNALS].disturbed) { - return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); - } + if (!isNaN(x) && opts.clamp) { + x = evenRound(x); - this[INTERNALS].disturbed = true; + if (x < lowerBound) x = lowerBound; + if (x > upperBound) x = upperBound; + return x; + } - if (this[INTERNALS].error) { - return Body.Promise.reject(this[INTERNALS].error); - } + if (!Number.isFinite(x) || x === 0) { + return 0; + } - let body = this.body; + x = sign(x) * Math.floor(Math.abs(x)); + x = x % moduloVal; - // body is null - if (body === null) { - return Body.Promise.resolve(Buffer.alloc(0)); - } + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal; + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal; + } else if (x === -0) { // don't return negative zero + return 0; + } + } - // body is blob - if (isBlob(body)) { - body = body.stream(); - } + return x; + } +} - // body is buffer - if (Buffer.isBuffer(body)) { - return Body.Promise.resolve(body); - } +conversions["void"] = function () { + return undefined; +}; - // istanbul ignore if: should never happen - if (!(body instanceof Stream)) { - return Body.Promise.resolve(Buffer.alloc(0)); - } +conversions["boolean"] = function (val) { + return !!val; +}; - // body is stream - // get ready to actually consume the body - let accum = []; - let accumBytes = 0; - let abort = false; +conversions["byte"] = createNumberConversion(8, { unsigned: false }); +conversions["octet"] = createNumberConversion(8, { unsigned: true }); - return new Body.Promise(function (resolve, reject) { - let resTimeout; +conversions["short"] = createNumberConversion(16, { unsigned: false }); +conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - // allow timeout on slow response body - if (_this4.timeout) { - resTimeout = setTimeout(function () { - abort = true; - reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); - }, _this4.timeout); - } +conversions["long"] = createNumberConversion(32, { unsigned: false }); +conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - // handle stream errors - body.on('error', function (err) { - if (err.name === 'AbortError') { - // if the request was aborted, reject with this Error - abort = true; - reject(err); - } else { - // other errors, such as incorrect content-encoding - reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); - } - }); +conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); +conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - body.on('data', function (chunk) { - if (abort || chunk === null) { - return; - } +conversions["double"] = function (V) { + const x = +V; - if (_this4.size && accumBytes + chunk.length > _this4.size) { - abort = true; - reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); - return; - } + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite floating-point value"); + } - accumBytes += chunk.length; - accum.push(chunk); - }); + return x; +}; - body.on('end', function () { - if (abort) { - return; - } +conversions["unrestricted double"] = function (V) { + const x = +V; - clearTimeout(resTimeout); + if (isNaN(x)) { + throw new TypeError("Argument is NaN"); + } - try { - resolve(Buffer.concat(accum, accumBytes)); - } catch (err) { - // handle streams that have accumulated too much data (issue #414) - reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - }); -} + return x; +}; -/** - * Detect buffer encoding and convert to target encoding - * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding - * - * @param Buffer buffer Incoming buffer - * @param String encoding Target encoding - * @return String - */ -function convertBody(buffer, headers) { - if (typeof convert !== 'function') { - throw new Error('The package `encoding` must be installed to use the textConverted() function'); - } +// not quite valid, but good enough for JS +conversions["float"] = conversions["double"]; +conversions["unrestricted float"] = conversions["unrestricted double"]; - const ct = headers.get('content-type'); - let charset = 'utf-8'; - let res, str; +conversions["DOMString"] = function (V, opts) { + if (!opts) opts = {}; - // header - if (ct) { - res = /charset=([^;]*)/i.exec(ct); - } + if (opts.treatNullAsEmptyString && V === null) { + return ""; + } - // no charset in content type, peek at response body for at most 1024 bytes - str = buffer.slice(0, 1024).toString(); + return String(V); +}; - // html5 - if (!res && str) { - res = / 255) { + throw new TypeError("Argument is not a valid bytestring"); + } + } - // html4 - if (!res && str) { - res = / 0xDFFF) { + U.push(String.fromCodePoint(c)); + } else if (0xDC00 <= c && c <= 0xDFFF) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + const d = S.charCodeAt(i + 1); + if (0xDC00 <= d && d <= 0xDFFF) { + const a = c & 0x3FF; + const b = d & 0x3FF; + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); + ++i; + } else { + U.push(String.fromCodePoint(0xFFFD)); + } + } + } + } - // xml - if (!res && str) { - res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); - } + return U.join(''); +}; - // found charset - if (res) { - charset = res.pop(); +conversions["Date"] = function (V, opts) { + if (!(V instanceof Date)) { + throw new TypeError("Argument is not a Date object"); + } + if (isNaN(V)) { + return undefined; + } - // prevent decode issues when sites use incorrect encoding - // ref: https://hsivonen.fi/encoding-menu/ - if (charset === 'gb2312' || charset === 'gbk') { - charset = 'gb18030'; - } - } + return V; +}; - // turn raw buffers into a single utf-8 buffer - return convert(buffer, 'UTF-8', charset).toString(); -} +conversions["RegExp"] = function (V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V); + } -/** - * Detect a URLSearchParams object - * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 - * - * @param Object obj Object to detect by type or brand - * @return String - */ -function isURLSearchParams(obj) { - // Duck-typing as a necessary condition. - if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { - return false; - } + return V; +}; - // Brand-checking and more duck-typing as optional condition. - return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; -} -/** - * Check if `obj` is a W3C `Blob` object (which `File` inherits from) - * @param {*} obj - * @return {boolean} - */ -function isBlob(obj) { - return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); -} +/***/ }), -/** - * Clone body given Res/Req instance - * - * @param Mixed instance Response or Request instance - * @return Mixed - */ -function clone(instance) { - let p1, p2; - let body = instance.body; +/***/ 8262: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // don't allow cloning a used body - if (instance.bodyUsed) { - throw new Error('cannot clone body after it is used'); - } - - // check that body is a stream and not form-data object - // note: we can't clone the form-data object without having it as a dependency - if (body instanceof Stream && typeof body.getBoundary !== 'function') { - // tee instance body - p1 = new PassThrough(); - p2 = new PassThrough(); - body.pipe(p1); - body.pipe(p2); - // set instance body to teed body and return the other teed body - instance[INTERNALS].body = p1; - body = p2; - } +"use strict"; - return body; -} +const usm = __nccwpck_require__(33); -/** - * Performs the operation "extract a `Content-Type` value from |object|" as - * specified in the specification: - * https://fetch.spec.whatwg.org/#concept-bodyinit-extract - * - * This function assumes that instance.body is present. - * - * @param Mixed instance Any options.body input - */ -function extractContentType(body) { - if (body === null) { - // body is null - return null; - } else if (typeof body === 'string') { - // body is string - return 'text/plain;charset=UTF-8'; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - return 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isBlob(body)) { - // body is blob - return body.type || null; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return null; - } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - return null; - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - return null; - } else if (typeof body.getBoundary === 'function') { - // detect form data input from form-data module - return `multipart/form-data;boundary=${body.getBoundary()}`; - } else if (body instanceof Stream) { - // body is stream - // can't really do much about this - return null; - } else { - // Body constructor defaults other things to string - return 'text/plain;charset=UTF-8'; - } -} +exports.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0]; + const base = constructorArgs[1]; -/** - * The Fetch Standard treats this as if "total bytes" is a property on the body. - * For us, we have to explicitly get it with a function. - * - * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes - * - * @param Body instance Instance of Body - * @return Number? Number of bytes, or null if not possible - */ -function getTotalBytes(instance) { - const body = instance.body; + let parsedBase = null; + if (base !== undefined) { + parsedBase = usm.basicURLParse(base); + if (parsedBase === "failure") { + throw new TypeError("Invalid base URL"); + } + } + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } - if (body === null) { - // body is null - return 0; - } else if (isBlob(body)) { - return body.size; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return body.length; - } else if (body && typeof body.getLengthSync === 'function') { - // detect form data input from form-data module - if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x - body.hasKnownLength && body.hasKnownLength()) { - // 2.x - return body.getLengthSync(); - } - return null; - } else { - // body is stream - return null; - } -} + this._url = parsedURL; -/** - * Write a Body to a Node.js WritableStream (e.g. http.Request) object. - * - * @param Body instance Instance of Body - * @return Void - */ -function writeToStream(dest, instance) { - const body = instance.body; + // TODO: query stuff + } + get href() { + return usm.serializeURL(this._url); + } - if (body === null) { - // body is null - dest.end(); - } else if (isBlob(body)) { - body.stream().pipe(dest); - } else if (Buffer.isBuffer(body)) { - // body is buffer - dest.write(body); - dest.end(); - } else { - // body is stream - body.pipe(dest); - } -} + set href(v) { + const parsedURL = usm.basicURLParse(v); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } -// expose Promise -Body.Promise = global.Promise; + this._url = parsedURL; + } -/** - * headers.js - * - * Headers class offers convenient helpers - */ + get origin() { + return usm.serializeURLOrigin(this._url); + } -const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; + get protocol() { + return this._url.scheme + ":"; + } -function validateName(name) { - name = `${name}`; - if (invalidTokenRegex.test(name) || name === '') { - throw new TypeError(`${name} is not a legal HTTP header name`); - } -} + set protocol(v) { + usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); + } -function validateValue(value) { - value = `${value}`; - if (invalidHeaderCharRegex.test(value)) { - throw new TypeError(`${value} is not a legal HTTP header value`); - } -} + get username() { + return this._url.username; + } -/** - * Find the key in the map object given a header name. - * - * Returns undefined if not found. - * - * @param String name Header name - * @return String|Undefined - */ -function find(map, name) { - name = name.toLowerCase(); - for (const key in map) { - if (key.toLowerCase() === name) { - return key; - } - } - return undefined; -} + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } -const MAP = Symbol('map'); -class Headers { - /** - * Headers class - * - * @param Object headers Response headers - * @return Void - */ - constructor() { - let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + usm.setTheUsername(this._url, v); + } - this[MAP] = Object.create(null); + get password() { + return this._url.password; + } - if (init instanceof Headers) { - const rawHeaders = init.raw(); - const headerNames = Object.keys(rawHeaders); + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - for (const headerName of headerNames) { - for (const value of rawHeaders[headerName]) { - this.append(headerName, value); - } - } + usm.setThePassword(this._url, v); + } - return; - } + get host() { + const url = this._url; - // We don't worry about converting prop to ByteString here as append() - // will handle it. - if (init == null) ; else if (typeof init === 'object') { - const method = init[Symbol.iterator]; - if (method != null) { - if (typeof method !== 'function') { - throw new TypeError('Header pairs must be iterable'); - } + if (url.host === null) { + return ""; + } - // sequence> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { - throw new TypeError('Each header pair must be iterable'); - } - pairs.push(Array.from(pair)); - } + if (url.port === null) { + return usm.serializeHost(url.host); + } - for (const pair of pairs) { - if (pair.length !== 2) { - throw new TypeError('Each header pair must be a name/value tuple'); - } - this.append(pair[0], pair[1]); - } - } else { - // record - for (const key of Object.keys(init)) { - const value = init[key]; - this.append(key, value); - } - } - } else { - throw new TypeError('Provided initializer must be an object'); - } - } + return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); + } - /** - * Return combined header value given name - * - * @param String name Header name - * @return Mixed - */ - get(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key === undefined) { - return null; - } + set host(v) { + if (this._url.cannotBeABaseURL) { + return; + } - return this[MAP][key].join(', '); - } + usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); + } - /** - * Iterate over all headers - * - * @param Function callback Executed for each item with parameters (value, name, thisArg) - * @param Boolean thisArg `this` context for callback function - * @return Void - */ - forEach(callback) { - let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + get hostname() { + if (this._url.host === null) { + return ""; + } - let pairs = getHeaders(this); - let i = 0; - while (i < pairs.length) { - var _pairs$i = pairs[i]; - const name = _pairs$i[0], - value = _pairs$i[1]; + return usm.serializeHost(this._url.host); + } - callback.call(thisArg, value, name, this); - pairs = getHeaders(this); - i++; - } - } + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return; + } - /** - * Overwrite header values given name - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - set(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - this[MAP][key !== undefined ? key : name] = [value]; - } + usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); + } - /** - * Append a value onto existing header - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - append(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - if (key !== undefined) { - this[MAP][key].push(value); - } else { - this[MAP][name] = [value]; - } - } + get port() { + if (this._url.port === null) { + return ""; + } - /** - * Check for header name existence - * - * @param String name Header name - * @return Boolean - */ - has(name) { - name = `${name}`; - validateName(name); - return find(this[MAP], name) !== undefined; - } + return usm.serializeInteger(this._url.port); + } - /** - * Delete all header values given name - * - * @param String name Header name - * @return Void - */ - delete(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key !== undefined) { - delete this[MAP][key]; - } - } + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - /** - * Return raw headers (non-spec api) - * - * @return Object - */ - raw() { - return this[MAP]; - } + if (v === "") { + this._url.port = null; + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); + } + } - /** - * Get an iterator on keys. - * - * @return Iterator - */ - keys() { - return createHeadersIterator(this, 'key'); - } + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0]; + } - /** - * Get an iterator on values. - * - * @return Iterator - */ - values() { - return createHeadersIterator(this, 'value'); - } + if (this._url.path.length === 0) { + return ""; + } - /** - * Get an iterator on entries. - * - * This is the default iterator of the Headers object. - * - * @return Iterator - */ - [Symbol.iterator]() { - return createHeadersIterator(this, 'key+value'); - } -} -Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + return "/" + this._url.path.join("/"); + } -Object.defineProperty(Headers.prototype, Symbol.toStringTag, { - value: 'Headers', - writable: false, - enumerable: false, - configurable: true -}); + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return; + } -Object.defineProperties(Headers.prototype, { - get: { enumerable: true }, - forEach: { enumerable: true }, - set: { enumerable: true }, - append: { enumerable: true }, - has: { enumerable: true }, - delete: { enumerable: true }, - keys: { enumerable: true }, - values: { enumerable: true }, - entries: { enumerable: true } -}); + this._url.path = []; + usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); + } -function getHeaders(headers) { - let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } - const keys = Object.keys(headers[MAP]).sort(); - return keys.map(kind === 'key' ? function (k) { - return k.toLowerCase(); - } : kind === 'value' ? function (k) { - return headers[MAP][k].join(', '); - } : function (k) { - return [k.toLowerCase(), headers[MAP][k].join(', ')]; - }); -} + return "?" + this._url.query; + } -const INTERNAL = Symbol('internal'); + set search(v) { + // TODO: query stuff -function createHeadersIterator(target, kind) { - const iterator = Object.create(HeadersIteratorPrototype); - iterator[INTERNAL] = { - target, - kind, - index: 0 - }; - return iterator; -} + const url = this._url; -const HeadersIteratorPrototype = Object.setPrototypeOf({ - next() { - // istanbul ignore if - if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { - throw new TypeError('Value of `this` is not a HeadersIterator'); - } + if (v === "") { + url.query = null; + return; + } - var _INTERNAL = this[INTERNAL]; - const target = _INTERNAL.target, - kind = _INTERNAL.kind, - index = _INTERNAL.index; + const input = v[0] === "?" ? v.substring(1) : v; + url.query = ""; + usm.basicURLParse(input, { url, stateOverride: "query" }); + } - const values = getHeaders(target, kind); - const len = values.length; - if (index >= len) { - return { - value: undefined, - done: true - }; - } + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } - this[INTERNAL].index = index + 1; + return "#" + this._url.fragment; + } - return { - value: values[index], - done: false - }; - } -}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + set hash(v) { + if (v === "") { + this._url.fragment = null; + return; + } -Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { - value: 'HeadersIterator', - writable: false, - enumerable: false, - configurable: true -}); + const input = v[0] === "#" ? v.substring(1) : v; + this._url.fragment = ""; + usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); + } -/** - * Export the Headers object in a form that Node.js can consume. - * - * @param Headers headers - * @return Object - */ -function exportNodeCompatibleHeaders(headers) { - const obj = Object.assign({ __proto__: null }, headers[MAP]); + toJSON() { + return this.href; + } +}; - // http.request() only supports string as Host header. This hack makes - // specifying custom Host header possible. - const hostHeaderKey = find(headers[MAP], 'Host'); - if (hostHeaderKey !== undefined) { - obj[hostHeaderKey] = obj[hostHeaderKey][0]; - } - return obj; -} +/***/ }), -/** - * Create a Headers object from an object of headers, ignoring those that do - * not conform to HTTP grammar productions. - * - * @param Object obj Object of headers - * @return Headers - */ -function createHeadersLenient(obj) { - const headers = new Headers(); - for (const name of Object.keys(obj)) { - if (invalidTokenRegex.test(name)) { - continue; - } - if (Array.isArray(obj[name])) { - for (const val of obj[name]) { - if (invalidHeaderCharRegex.test(val)) { - continue; - } - if (headers[MAP][name] === undefined) { - headers[MAP][name] = [val]; - } else { - headers[MAP][name].push(val); - } - } - } else if (!invalidHeaderCharRegex.test(obj[name])) { - headers[MAP][name] = [obj[name]]; - } - } - return headers; -} +/***/ 653: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const INTERNALS$1 = Symbol('Response internals'); +"use strict"; -// fix an issue where "STATUS_CODES" aren't a named export for node <10 -const STATUS_CODES = http.STATUS_CODES; -/** - * Response class - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -class Response { - constructor() { - let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +const conversions = __nccwpck_require__(5871); +const utils = __nccwpck_require__(276); +const Impl = __nccwpck_require__(8262); - Body.call(this, body, opts); +const impl = utils.implSymbol; - const status = opts.status || 200; - const headers = new Headers(opts.headers); +function URL(url) { + if (!this || this[impl] || !(this instanceof URL)) { + throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); + } + if (arguments.length < 1) { + throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); + } + const args = []; + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i]; + } + args[0] = conversions["USVString"](args[0]); + if (args[1] !== undefined) { + args[1] = conversions["USVString"](args[1]); + } - if (body != null && !headers.has('Content-Type')) { - const contentType = extractContentType(body); - if (contentType) { - headers.append('Content-Type', contentType); - } - } + module.exports.setup(this, args); +} - this[INTERNALS$1] = { - url: opts.url, - status, - statusText: opts.statusText || STATUS_CODES[status], - headers, - counter: opts.counter - }; - } +URL.prototype.toJSON = function toJSON() { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + const args = []; + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i]; + } + return this[impl].toJSON.apply(this[impl], args); +}; +Object.defineProperty(URL.prototype, "href", { + get() { + return this[impl].href; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].href = V; + }, + enumerable: true, + configurable: true +}); - get url() { - return this[INTERNALS$1].url || ''; - } +URL.prototype.toString = function () { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + return this.href; +}; - get status() { - return this[INTERNALS$1].status; - } +Object.defineProperty(URL.prototype, "origin", { + get() { + return this[impl].origin; + }, + enumerable: true, + configurable: true +}); - /** - * Convenience property representing if the request ended normally - */ - get ok() { - return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; - } +Object.defineProperty(URL.prototype, "protocol", { + get() { + return this[impl].protocol; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].protocol = V; + }, + enumerable: true, + configurable: true +}); - get redirected() { - return this[INTERNALS$1].counter > 0; - } +Object.defineProperty(URL.prototype, "username", { + get() { + return this[impl].username; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].username = V; + }, + enumerable: true, + configurable: true +}); - get statusText() { - return this[INTERNALS$1].statusText; - } +Object.defineProperty(URL.prototype, "password", { + get() { + return this[impl].password; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].password = V; + }, + enumerable: true, + configurable: true +}); - get headers() { - return this[INTERNALS$1].headers; - } +Object.defineProperty(URL.prototype, "host", { + get() { + return this[impl].host; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].host = V; + }, + enumerable: true, + configurable: true +}); - /** - * Clone this response - * - * @return Response - */ - clone() { - return new Response(clone(this), { - url: this.url, - status: this.status, - statusText: this.statusText, - headers: this.headers, - ok: this.ok, - redirected: this.redirected - }); - } -} - -Body.mixIn(Response.prototype); - -Object.defineProperties(Response.prototype, { - url: { enumerable: true }, - status: { enumerable: true }, - ok: { enumerable: true }, - redirected: { enumerable: true }, - statusText: { enumerable: true }, - headers: { enumerable: true }, - clone: { enumerable: true } +Object.defineProperty(URL.prototype, "hostname", { + get() { + return this[impl].hostname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hostname = V; + }, + enumerable: true, + configurable: true }); -Object.defineProperty(Response.prototype, Symbol.toStringTag, { - value: 'Response', - writable: false, - enumerable: false, - configurable: true +Object.defineProperty(URL.prototype, "port", { + get() { + return this[impl].port; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].port = V; + }, + enumerable: true, + configurable: true }); -const INTERNALS$2 = Symbol('Request internals'); -const URL = Url.URL || whatwgUrl.URL; - -// fix an issue where "format", "parse" aren't a named export for node <10 -const parse_url = Url.parse; -const format_url = Url.format; - -/** - * Wrapper around `new URL` to handle arbitrary URLs - * - * @param {string} urlStr - * @return {void} - */ -function parseURL(urlStr) { - /* - Check whether the URL is absolute or not - Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 - Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 - */ - if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { - urlStr = new URL(urlStr).toString(); - } - - // Fallback to old implementation for arbitrary URLs - return parse_url(urlStr); -} - -const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; - -/** - * Check if a value is an instance of Request. - * - * @param Mixed input - * @return Boolean - */ -function isRequest(input) { - return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; -} - -function isAbortSignal(signal) { - const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); - return !!(proto && proto.constructor.name === 'AbortSignal'); -} - -/** - * Request class - * - * @param Mixed input Url or Request instance - * @param Object init Custom options - * @return Void - */ -class Request { - constructor(input) { - let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - let parsedURL; - - // normalize input - if (!isRequest(input)) { - if (input && input.href) { - // in order to support Node.js' Url objects; though WHATWG's URL objects - // will fall into this branch also (since their `toString()` will return - // `href` property anyway) - parsedURL = parseURL(input.href); - } else { - // coerce input to a string before attempting to parse - parsedURL = parseURL(`${input}`); - } - input = {}; - } else { - parsedURL = parseURL(input.url); - } - - let method = init.method || input.method || 'GET'; - method = method.toUpperCase(); - - if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { - throw new TypeError('Request with GET/HEAD method cannot have body'); - } - - let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; +Object.defineProperty(URL.prototype, "pathname", { + get() { + return this[impl].pathname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].pathname = V; + }, + enumerable: true, + configurable: true +}); - Body.call(this, inputBody, { - timeout: init.timeout || input.timeout || 0, - size: init.size || input.size || 0 - }); +Object.defineProperty(URL.prototype, "search", { + get() { + return this[impl].search; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].search = V; + }, + enumerable: true, + configurable: true +}); - const headers = new Headers(init.headers || input.headers || {}); +Object.defineProperty(URL.prototype, "hash", { + get() { + return this[impl].hash; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hash = V; + }, + enumerable: true, + configurable: true +}); - if (inputBody != null && !headers.has('Content-Type')) { - const contentType = extractContentType(inputBody); - if (contentType) { - headers.append('Content-Type', contentType); - } - } - let signal = isRequest(input) ? input.signal : null; - if ('signal' in init) signal = init.signal; +module.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation; + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL.prototype); + this.setup(obj, constructorArgs, privateData); + return obj; + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {}; + privateData.wrapper = obj; - if (signal != null && !isAbortSignal(signal)) { - throw new TypeError('Expected signal to be an instanceof AbortSignal'); - } + obj[impl] = new Impl.implementation(constructorArgs, privateData); + obj[impl][utils.wrapperSymbol] = obj; + }, + interface: URL, + expose: { + Window: { URL: URL }, + Worker: { URL: URL } + } +}; - this[INTERNALS$2] = { - method, - redirect: init.redirect || input.redirect || 'follow', - headers, - parsedURL, - signal - }; - // node-fetch-only options - this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; - this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; - this.counter = init.counter || input.counter || 0; - this.agent = init.agent || input.agent; - } - get method() { - return this[INTERNALS$2].method; - } +/***/ }), - get url() { - return format_url(this[INTERNALS$2].parsedURL); - } +/***/ 3323: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - get headers() { - return this[INTERNALS$2].headers; - } +"use strict"; - get redirect() { - return this[INTERNALS$2].redirect; - } - get signal() { - return this[INTERNALS$2].signal; - } +exports.URL = __nccwpck_require__(653)["interface"]; +exports.serializeURL = __nccwpck_require__(33).serializeURL; +exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; +exports.basicURLParse = __nccwpck_require__(33).basicURLParse; +exports.setTheUsername = __nccwpck_require__(33).setTheUsername; +exports.setThePassword = __nccwpck_require__(33).setThePassword; +exports.serializeHost = __nccwpck_require__(33).serializeHost; +exports.serializeInteger = __nccwpck_require__(33).serializeInteger; +exports.parseURL = __nccwpck_require__(33).parseURL; - /** - * Clone this request - * - * @return Request - */ - clone() { - return new Request(this); - } -} -Body.mixIn(Request.prototype); +/***/ }), -Object.defineProperty(Request.prototype, Symbol.toStringTag, { - value: 'Request', - writable: false, - enumerable: false, - configurable: true -}); - -Object.defineProperties(Request.prototype, { - method: { enumerable: true }, - url: { enumerable: true }, - headers: { enumerable: true }, - redirect: { enumerable: true }, - clone: { enumerable: true }, - signal: { enumerable: true } -}); - -/** - * Convert a Request to Node.js http request options. - * - * @param Request A Request instance - * @return Object The options object to be passed to http.request - */ -function getNodeRequestOptions(request) { - const parsedURL = request[INTERNALS$2].parsedURL; - const headers = new Headers(request[INTERNALS$2].headers); - - // fetch step 1.3 - if (!headers.has('Accept')) { - headers.set('Accept', '*/*'); - } - - // Basic fetch - if (!parsedURL.protocol || !parsedURL.hostname) { - throw new TypeError('Only absolute URLs are supported'); - } - - if (!/^https?:$/.test(parsedURL.protocol)) { - throw new TypeError('Only HTTP(S) protocols are supported'); - } - - if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { - throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); - } - - // HTTP-network-or-cache fetch steps 2.4-2.7 - let contentLengthValue = null; - if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { - contentLengthValue = '0'; - } - if (request.body != null) { - const totalBytes = getTotalBytes(request); - if (typeof totalBytes === 'number') { - contentLengthValue = String(totalBytes); - } - } - if (contentLengthValue) { - headers.set('Content-Length', contentLengthValue); - } - - // HTTP-network-or-cache fetch step 2.11 - if (!headers.has('User-Agent')) { - headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); - } - - // HTTP-network-or-cache fetch step 2.15 - if (request.compress && !headers.has('Accept-Encoding')) { - headers.set('Accept-Encoding', 'gzip,deflate'); - } - - let agent = request.agent; - if (typeof agent === 'function') { - agent = agent(parsedURL); - } - - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close'); - } - - // HTTP-network fetch step 4.2 - // chunked encoding is handled by Node.js - - return Object.assign({}, parsedURL, { - method: request.method, - headers: exportNodeCompatibleHeaders(headers), - agent - }); -} - -/** - * abort-error.js - * - * AbortError interface for cancelled requests - */ - -/** - * Create AbortError instance - * - * @param String message Error message for human - * @return AbortError - */ -function AbortError(message) { - Error.call(this, message); - - this.type = 'aborted'; - this.message = message; - - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} - -AbortError.prototype = Object.create(Error.prototype); -AbortError.prototype.constructor = AbortError; -AbortError.prototype.name = 'AbortError'; - -const URL$1 = Url.URL || whatwgUrl.URL; - -// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 -const PassThrough$1 = Stream.PassThrough; - -const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { - const orig = new URL$1(original).hostname; - const dest = new URL$1(destination).hostname; - - return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); -}; - -/** - * Fetch function - * - * @param Mixed url Absolute url or Request instance - * @param Object opts Fetch options - * @return Promise - */ -function fetch(url, opts) { - - // allow custom promise - if (!fetch.Promise) { - throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); - } - - Body.Promise = fetch.Promise; - - // wrap http.request into fetch - return new fetch.Promise(function (resolve, reject) { - // build request object - const request = new Request(url, opts); - const options = getNodeRequestOptions(request); - - const send = (options.protocol === 'https:' ? https : http).request; - const signal = request.signal; - - let response = null; - - const abort = function abort() { - let error = new AbortError('The user aborted a request.'); - reject(error); - if (request.body && request.body instanceof Stream.Readable) { - request.body.destroy(error); - } - if (!response || !response.body) return; - response.body.emit('error', error); - }; - - if (signal && signal.aborted) { - abort(); - return; - } - - const abortAndFinalize = function abortAndFinalize() { - abort(); - finalize(); - }; - - // send request - const req = send(options); - let reqTimeout; - - if (signal) { - signal.addEventListener('abort', abortAndFinalize); - } - - function finalize() { - req.abort(); - if (signal) signal.removeEventListener('abort', abortAndFinalize); - clearTimeout(reqTimeout); - } - - if (request.timeout) { - req.once('socket', function (socket) { - reqTimeout = setTimeout(function () { - reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); - finalize(); - }, request.timeout); - }); - } - - req.on('error', function (err) { - reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); - finalize(); - }); - - req.on('response', function (res) { - clearTimeout(reqTimeout); - - const headers = createHeadersLenient(res.headers); - - // HTTP fetch step 5 - if (fetch.isRedirect(res.statusCode)) { - // HTTP fetch step 5.2 - const location = headers.get('Location'); - - // HTTP fetch step 5.3 - let locationURL = null; - try { - locationURL = location === null ? null : new URL$1(location, request.url).toString(); - } catch (err) { - // error here can only be invalid URL in Location: header - // do not throw when options.redirect == manual - // let the user extract the errorneous redirect URL - if (request.redirect !== 'manual') { - reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); - finalize(); - return; - } - } - - // HTTP fetch step 5.5 - switch (request.redirect) { - case 'error': - reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); - finalize(); - return; - case 'manual': - // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. - if (locationURL !== null) { - // handle corrupted header - try { - headers.set('Location', locationURL); - } catch (err) { - // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request - reject(err); - } - } - break; - case 'follow': - // HTTP-redirect fetch step 2 - if (locationURL === null) { - break; - } - - // HTTP-redirect fetch step 5 - if (request.counter >= request.follow) { - reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 6 (counter increment) - // Create a new Request object. - const requestOpts = { - headers: new Headers(request.headers), - follow: request.follow, - counter: request.counter + 1, - agent: request.agent, - compress: request.compress, - method: request.method, - body: request.body, - signal: request.signal, - timeout: request.timeout, - size: request.size - }; - - if (!isDomainOrSubdomain(request.url, locationURL)) { - for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { - requestOpts.headers.delete(name); - } - } - - // HTTP-redirect fetch step 9 - if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { - reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 11 - if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { - requestOpts.method = 'GET'; - requestOpts.body = undefined; - requestOpts.headers.delete('content-length'); - } - - // HTTP-redirect fetch step 15 - resolve(fetch(new Request(locationURL, requestOpts))); - finalize(); - return; - } - } - - // prepare response - res.once('end', function () { - if (signal) signal.removeEventListener('abort', abortAndFinalize); - }); - let body = res.pipe(new PassThrough$1()); - - const response_options = { - url: request.url, - status: res.statusCode, - statusText: res.statusMessage, - headers: headers, - size: request.size, - timeout: request.timeout, - counter: request.counter - }; - - // HTTP-network fetch step 12.1.1.3 - const codings = headers.get('Content-Encoding'); - - // HTTP-network fetch step 12.1.1.4: handle content codings - - // in following scenarios we ignore compression support - // 1. compression support is disabled - // 2. HEAD request - // 3. no Content-Encoding header - // 4. no content response (204) - // 5. content not modified response (304) - if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { - response = new Response(body, response_options); - resolve(response); - return; - } - - // For Node v6+ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - const zlibOptions = { - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH - }; - - // for gzip - if (codings == 'gzip' || codings == 'x-gzip') { - body = body.pipe(zlib.createGunzip(zlibOptions)); - response = new Response(body, response_options); - resolve(response); - return; - } - - // for deflate - if (codings == 'deflate' || codings == 'x-deflate') { - // handle the infamous raw deflate response from old servers - // a hack for old IIS and Apache servers - const raw = res.pipe(new PassThrough$1()); - raw.once('data', function (chunk) { - // see http://stackoverflow.com/questions/37519828 - if ((chunk[0] & 0x0F) === 0x08) { - body = body.pipe(zlib.createInflate()); - } else { - body = body.pipe(zlib.createInflateRaw()); - } - response = new Response(body, response_options); - resolve(response); - }); - return; - } - - // for br - if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { - body = body.pipe(zlib.createBrotliDecompress()); - response = new Response(body, response_options); - resolve(response); - return; - } - - // otherwise, use response as-is - response = new Response(body, response_options); - resolve(response); - }); - - writeToStream(req, request); - }); -} -/** - * Redirect code matching - * - * @param Number code Status code - * @return Boolean - */ -fetch.isRedirect = function (code) { - return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; -}; - -// expose Promise -fetch.Promise = global.Promise; - -module.exports = exports = fetch; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports; -exports.Headers = Headers; -exports.Request = Request; -exports.Response = Response; -exports.FetchError = FetchError; - - -/***/ }), - -/***/ 2299: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -var punycode = __nccwpck_require__(5477); -var mappingTable = __nccwpck_require__(1907); - -var PROCESSING_OPTIONS = { - TRANSITIONAL: 0, - NONTRANSITIONAL: 1 -}; - -function normalize(str) { // fix bug in v8 - return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); -} - -function findStatus(val) { - var start = 0; - var end = mappingTable.length - 1; - - while (start <= end) { - var mid = Math.floor((start + end) / 2); - - var target = mappingTable[mid]; - if (target[0][0] <= val && target[0][1] >= val) { - return target; - } else if (target[0][0] > val) { - end = mid - 1; - } else { - start = mid + 1; - } - } - - return null; -} - -var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; - -function countSymbols(string) { - return string - // replace every surrogate pair with a BMP symbol - .replace(regexAstralSymbols, '_') - // then get the length - .length; -} - -function mapChars(domain_name, useSTD3, processing_option) { - var hasError = false; - var processed = ""; - - var len = countSymbols(domain_name); - for (var i = 0; i < len; ++i) { - var codePoint = domain_name.codePointAt(i); - var status = findStatus(codePoint); - - switch (status[1]) { - case "disallowed": - hasError = true; - processed += String.fromCodePoint(codePoint); - break; - case "ignored": - break; - case "mapped": - processed += String.fromCodePoint.apply(String, status[2]); - break; - case "deviation": - if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { - processed += String.fromCodePoint.apply(String, status[2]); - } else { - processed += String.fromCodePoint(codePoint); - } - break; - case "valid": - processed += String.fromCodePoint(codePoint); - break; - case "disallowed_STD3_mapped": - if (useSTD3) { - hasError = true; - processed += String.fromCodePoint(codePoint); - } else { - processed += String.fromCodePoint.apply(String, status[2]); - } - break; - case "disallowed_STD3_valid": - if (useSTD3) { - hasError = true; - } - - processed += String.fromCodePoint(codePoint); - break; - } - } - - return { - string: processed, - error: hasError - }; -} - -var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; - -function validateLabel(label, processing_option) { - if (label.substr(0, 4) === "xn--") { - label = punycode.toUnicode(label); - processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; - } - - var error = false; - - if (normalize(label) !== label || - (label[3] === "-" && label[4] === "-") || - label[0] === "-" || label[label.length - 1] === "-" || - label.indexOf(".") !== -1 || - label.search(combiningMarksRegex) === 0) { - error = true; - } - - var len = countSymbols(label); - for (var i = 0; i < len; ++i) { - var status = findStatus(label.codePointAt(i)); - if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || - (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && - status[1] !== "valid" && status[1] !== "deviation")) { - error = true; - break; - } - } - - return { - label: label, - error: error - }; -} - -function processing(domain_name, useSTD3, processing_option) { - var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize(result.string); - - var labels = result.string.split("."); - for (var i = 0; i < labels.length; ++i) { - try { - var validation = validateLabel(labels[i]); - labels[i] = validation.label; - result.error = result.error || validation.error; - } catch(e) { - result.error = true; - } - } - - return { - string: labels.join("."), - error: result.error - }; -} - -module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { - var result = processing(domain_name, useSTD3, processing_option); - var labels = result.string.split("."); - labels = labels.map(function(l) { - try { - return punycode.toASCII(l); - } catch(e) { - result.error = true; - return l; - } - }); - - if (verifyDnsLength) { - var total = labels.slice(0, labels.length - 1).join(".").length; - if (total.length > 253 || total.length === 0) { - result.error = true; - } - - for (var i=0; i < labels.length; ++i) { - if (labels.length > 63 || labels.length === 0) { - result.error = true; - break; - } - } - } - - if (result.error) return null; - return labels.join("."); -}; - -module.exports.toUnicode = function(domain_name, useSTD3) { - var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - - return { - domain: result.string, - error: result.error - }; -}; - -module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - - -/***/ }), - -/***/ 5871: -/***/ ((module) => { - -"use strict"; - - -var conversions = {}; -module.exports = conversions; - -function sign(x) { - return x < 0 ? -1 : 1; -} - -function evenRound(x) { - // Round x to the nearest integer, choosing the even integer if it lies halfway between two. - if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) - return Math.floor(x); - } else { - return Math.round(x); - } -} - -function createNumberConversion(bitLength, typeOpts) { - if (!typeOpts.unsigned) { - --bitLength; - } - const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); - const upperBound = Math.pow(2, bitLength) - 1; - - const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); - const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - - return function(V, opts) { - if (!opts) opts = {}; - - let x = +V; - - if (opts.enforceRange) { - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite number"); - } - - x = sign(x) * Math.floor(Math.abs(x)); - if (x < lowerBound || x > upperBound) { - throw new TypeError("Argument is not in byte range"); - } - - return x; - } - - if (!isNaN(x) && opts.clamp) { - x = evenRound(x); - - if (x < lowerBound) x = lowerBound; - if (x > upperBound) x = upperBound; - return x; - } - - if (!Number.isFinite(x) || x === 0) { - return 0; - } - - x = sign(x) * Math.floor(Math.abs(x)); - x = x % moduloVal; - - if (!typeOpts.unsigned && x >= moduloBound) { - return x - moduloVal; - } else if (typeOpts.unsigned) { - if (x < 0) { - x += moduloVal; - } else if (x === -0) { // don't return negative zero - return 0; - } - } - - return x; - } -} - -conversions["void"] = function () { - return undefined; -}; - -conversions["boolean"] = function (val) { - return !!val; -}; - -conversions["byte"] = createNumberConversion(8, { unsigned: false }); -conversions["octet"] = createNumberConversion(8, { unsigned: true }); - -conversions["short"] = createNumberConversion(16, { unsigned: false }); -conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - -conversions["long"] = createNumberConversion(32, { unsigned: false }); -conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - -conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); -conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - -conversions["double"] = function (V) { - const x = +V; - - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite floating-point value"); - } - - return x; -}; - -conversions["unrestricted double"] = function (V) { - const x = +V; - - if (isNaN(x)) { - throw new TypeError("Argument is NaN"); - } - - return x; -}; - -// not quite valid, but good enough for JS -conversions["float"] = conversions["double"]; -conversions["unrestricted float"] = conversions["unrestricted double"]; - -conversions["DOMString"] = function (V, opts) { - if (!opts) opts = {}; - - if (opts.treatNullAsEmptyString && V === null) { - return ""; - } - - return String(V); -}; - -conversions["ByteString"] = function (V, opts) { - const x = String(V); - let c = undefined; - for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { - if (c > 255) { - throw new TypeError("Argument is not a valid bytestring"); - } - } - - return x; -}; - -conversions["USVString"] = function (V) { - const S = String(V); - const n = S.length; - const U = []; - for (let i = 0; i < n; ++i) { - const c = S.charCodeAt(i); - if (c < 0xD800 || c > 0xDFFF) { - U.push(String.fromCodePoint(c)); - } else if (0xDC00 <= c && c <= 0xDFFF) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - if (i === n - 1) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - const d = S.charCodeAt(i + 1); - if (0xDC00 <= d && d <= 0xDFFF) { - const a = c & 0x3FF; - const b = d & 0x3FF; - U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); - ++i; - } else { - U.push(String.fromCodePoint(0xFFFD)); - } - } - } - } - - return U.join(''); -}; - -conversions["Date"] = function (V, opts) { - if (!(V instanceof Date)) { - throw new TypeError("Argument is not a Date object"); - } - if (isNaN(V)) { - return undefined; - } - - return V; -}; - -conversions["RegExp"] = function (V, opts) { - if (!(V instanceof RegExp)) { - V = new RegExp(V); - } - - return V; -}; - - -/***/ }), - -/***/ 8262: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -const usm = __nccwpck_require__(33); - -exports.implementation = class URLImpl { - constructor(constructorArgs) { - const url = constructorArgs[0]; - const base = constructorArgs[1]; - - let parsedBase = null; - if (base !== undefined) { - parsedBase = usm.basicURLParse(base); - if (parsedBase === "failure") { - throw new TypeError("Invalid base URL"); - } - } - - const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - - // TODO: query stuff - } - - get href() { - return usm.serializeURL(this._url); - } - - set href(v) { - const parsedURL = usm.basicURLParse(v); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - } - - get origin() { - return usm.serializeURLOrigin(this._url); - } - - get protocol() { - return this._url.scheme + ":"; - } - - set protocol(v) { - usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); - } - - get username() { - return this._url.username; - } - - set username(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setTheUsername(this._url, v); - } - - get password() { - return this._url.password; - } - - set password(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setThePassword(this._url, v); - } - - get host() { - const url = this._url; - - if (url.host === null) { - return ""; - } - - if (url.port === null) { - return usm.serializeHost(url.host); - } - - return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); - } - - set host(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); - } - - get hostname() { - if (this._url.host === null) { - return ""; - } - - return usm.serializeHost(this._url.host); - } - - set hostname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); - } - - get port() { - if (this._url.port === null) { - return ""; - } - - return usm.serializeInteger(this._url.port); - } - - set port(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - if (v === "") { - this._url.port = null; - } else { - usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); - } - } - - get pathname() { - if (this._url.cannotBeABaseURL) { - return this._url.path[0]; - } - - if (this._url.path.length === 0) { - return ""; - } - - return "/" + this._url.path.join("/"); - } - - set pathname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - this._url.path = []; - usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); - } - - get search() { - if (this._url.query === null || this._url.query === "") { - return ""; - } - - return "?" + this._url.query; - } - - set search(v) { - // TODO: query stuff - - const url = this._url; - - if (v === "") { - url.query = null; - return; - } - - const input = v[0] === "?" ? v.substring(1) : v; - url.query = ""; - usm.basicURLParse(input, { url, stateOverride: "query" }); - } - - get hash() { - if (this._url.fragment === null || this._url.fragment === "") { - return ""; - } - - return "#" + this._url.fragment; - } - - set hash(v) { - if (v === "") { - this._url.fragment = null; - return; - } - - const input = v[0] === "#" ? v.substring(1) : v; - this._url.fragment = ""; - usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); - } - - toJSON() { - return this.href; - } -}; - - -/***/ }), - -/***/ 653: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const conversions = __nccwpck_require__(5871); -const utils = __nccwpck_require__(276); -const Impl = __nccwpck_require__(8262); - -const impl = utils.implSymbol; - -function URL(url) { - if (!this || this[impl] || !(this instanceof URL)) { - throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); - } - if (arguments.length < 1) { - throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); - } - const args = []; - for (let i = 0; i < arguments.length && i < 2; ++i) { - args[i] = arguments[i]; - } - args[0] = conversions["USVString"](args[0]); - if (args[1] !== undefined) { - args[1] = conversions["USVString"](args[1]); - } - - module.exports.setup(this, args); -} - -URL.prototype.toJSON = function toJSON() { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - const args = []; - for (let i = 0; i < arguments.length && i < 0; ++i) { - args[i] = arguments[i]; - } - return this[impl].toJSON.apply(this[impl], args); -}; -Object.defineProperty(URL.prototype, "href", { - get() { - return this[impl].href; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].href = V; - }, - enumerable: true, - configurable: true -}); - -URL.prototype.toString = function () { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - return this.href; -}; - -Object.defineProperty(URL.prototype, "origin", { - get() { - return this[impl].origin; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "protocol", { - get() { - return this[impl].protocol; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].protocol = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "username", { - get() { - return this[impl].username; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].username = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "password", { - get() { - return this[impl].password; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].password = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "host", { - get() { - return this[impl].host; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].host = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hostname", { - get() { - return this[impl].hostname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hostname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "port", { - get() { - return this[impl].port; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].port = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "pathname", { - get() { - return this[impl].pathname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].pathname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "search", { - get() { - return this[impl].search; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].search = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hash", { - get() { - return this[impl].hash; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hash = V; - }, - enumerable: true, - configurable: true -}); - - -module.exports = { - is(obj) { - return !!obj && obj[impl] instanceof Impl.implementation; - }, - create(constructorArgs, privateData) { - let obj = Object.create(URL.prototype); - this.setup(obj, constructorArgs, privateData); - return obj; - }, - setup(obj, constructorArgs, privateData) { - if (!privateData) privateData = {}; - privateData.wrapper = obj; - - obj[impl] = new Impl.implementation(constructorArgs, privateData); - obj[impl][utils.wrapperSymbol] = obj; - }, - interface: URL, - expose: { - Window: { URL: URL }, - Worker: { URL: URL } - } -}; - - - -/***/ }), - -/***/ 3323: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -exports.URL = __nccwpck_require__(653)["interface"]; -exports.serializeURL = __nccwpck_require__(33).serializeURL; -exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; -exports.basicURLParse = __nccwpck_require__(33).basicURLParse; -exports.setTheUsername = __nccwpck_require__(33).setTheUsername; -exports.setThePassword = __nccwpck_require__(33).setThePassword; -exports.serializeHost = __nccwpck_require__(33).serializeHost; -exports.serializeInteger = __nccwpck_require__(33).serializeInteger; -exports.parseURL = __nccwpck_require__(33).parseURL; - - -/***/ }), - -/***/ 33: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 33: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; @@ -13532,230 +11376,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/bumpVersion/bumpVersion.js b/.github/actions/javascript/bumpVersion/bumpVersion.ts similarity index 72% rename from .github/actions/javascript/bumpVersion/bumpVersion.js rename to .github/actions/javascript/bumpVersion/bumpVersion.ts index 647c295fdc52..ed4828367cf2 100644 --- a/.github/actions/javascript/bumpVersion/bumpVersion.js +++ b/.github/actions/javascript/bumpVersion/bumpVersion.ts @@ -1,17 +1,16 @@ -const {promisify} = require('util'); -const fs = require('fs'); -const exec = promisify(require('child_process').exec); -const _ = require('underscore'); -const core = require('@actions/core'); -const versionUpdater = require('../../../libs/versionUpdater'); -const {updateAndroidVersion, updateiOSVersion, generateAndroidVersionCode} = require('../../../libs/nativeVersionUpdater'); +import * as core from '@actions/core'; +import {exec as originalExec} from 'child_process'; +import fs from 'fs'; +import {promisify} from 'util'; +import {generateAndroidVersionCode, updateAndroidVersion, updateiOSVersion} from '@github/libs/nativeVersionUpdater'; +import * as versionUpdater from '@github/libs/versionUpdater'; + +const exec = promisify(originalExec); /** * Update the native app versions. - * - * @param {String} version */ -function updateNativeVersions(version) { +function updateNativeVersions(version: string) { console.log(`Updating native versions to ${version}`); // Update Android @@ -28,7 +27,7 @@ function updateNativeVersions(version) { // Update iOS try { const cfBundleVersion = updateiOSVersion(version); - if (_.isString(cfBundleVersion) && cfBundleVersion.split('.').length === 4) { + if (typeof cfBundleVersion === 'string' && cfBundleVersion.split('.').length === 4) { core.setOutput('NEW_IOS_VERSION', cfBundleVersion); console.log('Successfully updated iOS!'); } else { @@ -36,17 +35,19 @@ function updateNativeVersions(version) { } } catch (err) { console.error('Error updating iOS'); - core.setFailed(err); + if (err instanceof Error) { + core.setFailed(err); + } } } -let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {require: true}); -if (!semanticVersionLevel || !_.contains(versionUpdater.SEMANTIC_VERSION_LEVELS, semanticVersionLevel)) { +let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {required: true}); +if (!semanticVersionLevel || !Object.keys(versionUpdater.SEMANTIC_VERSION_LEVELS).includes(semanticVersionLevel)) { semanticVersionLevel = versionUpdater.SEMANTIC_VERSION_LEVELS.BUILD; console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}`, `Defaulting to: ${semanticVersionLevel}`); } -const {version: previousVersion} = JSON.parse(fs.readFileSync('./package.json')); +const {version: previousVersion} = JSON.parse(fs.readFileSync('./package.json').toString()); const newVersion = versionUpdater.incrementVersion(previousVersion, semanticVersionLevel); console.log(`Previous version: ${previousVersion}`, `New version: ${newVersion}`); diff --git a/.github/actions/javascript/bumpVersion/index.js b/.github/actions/javascript/bumpVersion/index.js index 8fe84446ba82..d2d8c4e0d118 100644 --- a/.github/actions/javascript/bumpVersion/index.js +++ b/.github/actions/javascript/bumpVersion/index.js @@ -4,105 +4,6 @@ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 322: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -const {execSync} = __nccwpck_require__(2081); -const fs = (__nccwpck_require__(7147).promises); -const path = __nccwpck_require__(1017); -const getMajorVersion = __nccwpck_require__(6688); -const getMinorVersion = __nccwpck_require__(8447); -const getPatchVersion = __nccwpck_require__(2866); -const getBuildVersion = __nccwpck_require__(4016); - -// Filepath constants -const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path.resolve(__dirname, '../../android/app/build.gradle') : './android/app/build.gradle'; -const PLIST_PATH = './ios/NewExpensify/Info.plist'; -const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist'; -const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist'; - -exports.BUILD_GRADLE_PATH = BUILD_GRADLE_PATH; -exports.PLIST_PATH = PLIST_PATH; -exports.PLIST_PATH_TEST = PLIST_PATH_TEST; - -/** - * Pad a number to be two digits (with leading zeros if necessary). - * - * @param {Number} number - Must be an integer. - * @returns {String} - A string representation of the number with length 2. - */ -function padToTwoDigits(number) { - if (number >= 10) { - return number.toString(); - } - return `0${number.toString()}`; -} - -/** - * Generate the 10-digit versionCode for android. - * This version code allocates two digits each for PREFIX, MAJOR, MINOR, PATCH, and BUILD versions. - * As a result, our max version is 99.99.99-99. - * - * @param {String} npmVersion - * @returns {String} - */ -exports.generateAndroidVersionCode = function generateAndroidVersionCode(npmVersion) { - // All Android versions will be prefixed with '10' due to previous versioning - const prefix = '10'; - return ''.concat( - prefix, - padToTwoDigits(getMajorVersion(npmVersion) || 0), - padToTwoDigits(getMinorVersion(npmVersion) || 0), - padToTwoDigits(getPatchVersion(npmVersion) || 0), - padToTwoDigits(getBuildVersion(npmVersion) || 0), - ); -}; - -/** - * Update the Android app versionName and versionCode. - * - * @param {String} versionName - * @param {String} versionCode - * @returns {Promise} - */ -exports.updateAndroidVersion = function updateAndroidVersion(versionName, versionCode) { - console.log('Updating android:', `versionName: ${versionName}`, `versionCode: ${versionCode}`); - return fs - .readFile(BUILD_GRADLE_PATH, {encoding: 'utf8'}) - .then((content) => { - let updatedContent = content.toString().replace(/versionName "([0-9.-]*)"/, `versionName "${versionName}"`); - return (updatedContent = updatedContent.replace(/versionCode ([0-9]*)/, `versionCode ${versionCode}`)); - }) - .then((updatedContent) => fs.writeFile(BUILD_GRADLE_PATH, updatedContent, {encoding: 'utf8'})); -}; - -/** - * Update the iOS app version. - * Updates the CFBundleShortVersionString and the CFBundleVersion. - * - * @param {String} version - * @returns {String} - */ -exports.updateiOSVersion = function updateiOSVersion(version) { - const shortVersion = version.split('-')[0]; - const cfVersion = version.includes('-') ? version.replace('-', '.') : `${version}.0`; - console.log('Updating iOS', `CFBundleShortVersionString: ${shortVersion}`, `CFBundleVersion: ${cfVersion}`); - - // Update Plists - execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH}`); - execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_TEST}`); - execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_NSE}`); - execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH}`); - execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_TEST}`); - execSync(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_NSE}`); - - // Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml - return cfVersion; -}; - - -/***/ }), - /***/ 8007: /***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { @@ -3646,6 +3547,186 @@ function version(uuid) { var _default = version; exports["default"] = _default; +/***/ }), + +/***/ 7361: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core = __importStar(__nccwpck_require__(2186)); +const child_process_1 = __nccwpck_require__(2081); +const fs_1 = __importDefault(__nccwpck_require__(7147)); +const util_1 = __nccwpck_require__(3837); +const nativeVersionUpdater_1 = __nccwpck_require__(9095); +const versionUpdater = __importStar(__nccwpck_require__(8007)); +const exec = (0, util_1.promisify)(child_process_1.exec); +/** + * Update the native app versions. + */ +function updateNativeVersions(version) { + console.log(`Updating native versions to ${version}`); + // Update Android + const androidVersionCode = (0, nativeVersionUpdater_1.generateAndroidVersionCode)(version); + (0, nativeVersionUpdater_1.updateAndroidVersion)(version, androidVersionCode) + .then(() => { + console.log('Successfully updated Android!'); + }) + .catch((err) => { + console.error('Error updating Android'); + core.setFailed(err); + }); + // Update iOS + try { + const cfBundleVersion = (0, nativeVersionUpdater_1.updateiOSVersion)(version); + if (typeof cfBundleVersion === 'string' && cfBundleVersion.split('.').length === 4) { + core.setOutput('NEW_IOS_VERSION', cfBundleVersion); + console.log('Successfully updated iOS!'); + } + else { + core.setFailed(`Failed to set NEW_IOS_VERSION. CFBundleVersion: ${cfBundleVersion}`); + } + } + catch (err) { + console.error('Error updating iOS'); + if (err instanceof Error) { + core.setFailed(err); + } + } +} +let semanticVersionLevel = core.getInput('SEMVER_LEVEL', { required: true }); +if (!semanticVersionLevel || !Object.keys(versionUpdater.SEMANTIC_VERSION_LEVELS).includes(semanticVersionLevel)) { + semanticVersionLevel = versionUpdater.SEMANTIC_VERSION_LEVELS.BUILD; + console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}`, `Defaulting to: ${semanticVersionLevel}`); +} +const { version: previousVersion } = JSON.parse(fs_1.default.readFileSync('./package.json').toString()); +const newVersion = versionUpdater.incrementVersion(previousVersion, semanticVersionLevel); +console.log(`Previous version: ${previousVersion}`, `New version: ${newVersion}`); +updateNativeVersions(newVersion); +console.log(`Setting npm version to ${newVersion}`); +exec(`npm --no-git-tag-version version ${newVersion} -m "Update version to ${newVersion}"`) + .then(({ stdout }) => { + // NPM and native versions successfully updated, output new version + console.log(stdout); + core.setOutput('NEW_VERSION', newVersion); +}) + .catch(({ stdout, stderr }) => { + // Log errors and retry + console.log(stdout); + console.error(stderr); + core.setFailed('An error occurred in the `npm version` command'); +}); + + +/***/ }), + +/***/ 9095: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.PLIST_PATH_TEST = exports.PLIST_PATH = exports.BUILD_GRADLE_PATH = exports.generateAndroidVersionCode = exports.updateAndroidVersion = exports.updateiOSVersion = void 0; +const child_process_1 = __nccwpck_require__(2081); +const fs_1 = __nccwpck_require__(7147); +const path_1 = __importDefault(__nccwpck_require__(1017)); +const major_1 = __importDefault(__nccwpck_require__(6688)); +const minor_1 = __importDefault(__nccwpck_require__(8447)); +const patch_1 = __importDefault(__nccwpck_require__(2866)); +const prerelease_1 = __importDefault(__nccwpck_require__(4016)); +// Filepath constants +const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path_1.default.resolve(__dirname, '../../android/app/build.gradle') : './android/app/build.gradle'; +exports.BUILD_GRADLE_PATH = BUILD_GRADLE_PATH; +const PLIST_PATH = './ios/NewExpensify/Info.plist'; +exports.PLIST_PATH = PLIST_PATH; +const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist'; +exports.PLIST_PATH_TEST = PLIST_PATH_TEST; +const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist'; +/** + * Pad a number to be two digits (with leading zeros if necessary). + */ +function padToTwoDigits(value) { + if (value >= 10) { + return value.toString(); + } + return `0${value.toString()}`; +} +/** + * Generate the 10-digit versionCode for android. + * This version code allocates two digits each for PREFIX, MAJOR, MINOR, PATCH, and BUILD versions. + * As a result, our max version is 99.99.99-99. + */ +function generateAndroidVersionCode(npmVersion) { + // All Android versions will be prefixed with '10' due to previous versioning + const prefix = '10'; + return ''.concat(prefix, padToTwoDigits((0, major_1.default)(npmVersion) ?? 0), padToTwoDigits((0, minor_1.default)(npmVersion) ?? 0), padToTwoDigits((0, patch_1.default)(npmVersion) ?? 0), padToTwoDigits(Number((0, prerelease_1.default)(npmVersion)) ?? 0)); +} +exports.generateAndroidVersionCode = generateAndroidVersionCode; +/** + * Update the Android app versionName and versionCode. + */ +function updateAndroidVersion(versionName, versionCode) { + console.log('Updating android:', `versionName: ${versionName}`, `versionCode: ${versionCode}`); + return fs_1.promises + .readFile(BUILD_GRADLE_PATH, { encoding: 'utf8' }) + .then((content) => { + let updatedContent = content.toString().replace(/versionName "([0-9.-]*)"/, `versionName "${versionName}"`); + return (updatedContent = updatedContent.replace(/versionCode ([0-9]*)/, `versionCode ${versionCode}`)); + }) + .then((updatedContent) => fs_1.promises.writeFile(BUILD_GRADLE_PATH, updatedContent, { encoding: 'utf8' })); +} +exports.updateAndroidVersion = updateAndroidVersion; +/** + * Update the iOS app version. + * Updates the CFBundleShortVersionString and the CFBundleVersion. + */ +function updateiOSVersion(version) { + const shortVersion = version.split('-')[0]; + const cfVersion = version.includes('-') ? version.replace('-', '.') : `${version}.0`; + console.log('Updating iOS', `CFBundleShortVersionString: ${shortVersion}`, `CFBundleVersion: ${cfVersion}`); + // Update Plists + (0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH}`); + (0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_TEST}`); + (0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${shortVersion}" ${PLIST_PATH_NSE}`); + (0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH}`); + (0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_TEST}`); + (0, child_process_1.execSync)(`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${cfVersion}" ${PLIST_PATH_NSE}`); + // Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml + return cfVersion; +} +exports.updateiOSVersion = updateiOSVersion; + + /***/ }), /***/ 9491: @@ -5993,79 +6074,12 @@ module.exports = underscoreNodeF._; /******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/"; /******/ /************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. -(() => { -const {promisify} = __nccwpck_require__(3837); -const fs = __nccwpck_require__(7147); -const exec = promisify((__nccwpck_require__(2081).exec)); -const _ = __nccwpck_require__(5067); -const core = __nccwpck_require__(2186); -const versionUpdater = __nccwpck_require__(8007); -const {updateAndroidVersion, updateiOSVersion, generateAndroidVersionCode} = __nccwpck_require__(322); - -/** - * Update the native app versions. - * - * @param {String} version - */ -function updateNativeVersions(version) { - console.log(`Updating native versions to ${version}`); - - // Update Android - const androidVersionCode = generateAndroidVersionCode(version); - updateAndroidVersion(version, androidVersionCode) - .then(() => { - console.log('Successfully updated Android!'); - }) - .catch((err) => { - console.error('Error updating Android'); - core.setFailed(err); - }); - - // Update iOS - try { - const cfBundleVersion = updateiOSVersion(version); - if (_.isString(cfBundleVersion) && cfBundleVersion.split('.').length === 4) { - core.setOutput('NEW_IOS_VERSION', cfBundleVersion); - console.log('Successfully updated iOS!'); - } else { - core.setFailed(`Failed to set NEW_IOS_VERSION. CFBundleVersion: ${cfBundleVersion}`); - } - } catch (err) { - console.error('Error updating iOS'); - core.setFailed(err); - } -} - -let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {require: true}); -if (!semanticVersionLevel || !_.contains(versionUpdater.SEMANTIC_VERSION_LEVELS, semanticVersionLevel)) { - semanticVersionLevel = versionUpdater.SEMANTIC_VERSION_LEVELS.BUILD; - console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}`, `Defaulting to: ${semanticVersionLevel}`); -} - -const {version: previousVersion} = JSON.parse(fs.readFileSync('./package.json')); -const newVersion = versionUpdater.incrementVersion(previousVersion, semanticVersionLevel); -console.log(`Previous version: ${previousVersion}`, `New version: ${newVersion}`); - -updateNativeVersions(newVersion); - -console.log(`Setting npm version to ${newVersion}`); -exec(`npm --no-git-tag-version version ${newVersion} -m "Update version to ${newVersion}"`) - .then(({stdout}) => { - // NPM and native versions successfully updated, output new version - console.log(stdout); - core.setOutput('NEW_VERSION', newVersion); - }) - .catch(({stdout, stderr}) => { - // Log errors and retry - console.log(stdout); - console.error(stderr); - core.setFailed('An error occurred in the `npm version` command'); - }); - -})(); - -module.exports = __webpack_exports__; +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module is referenced by other modules so it can't be inlined +/******/ var __webpack_exports__ = __nccwpck_require__(7361); +/******/ module.exports = __webpack_exports__; +/******/ /******/ })() ; diff --git a/.github/actions/javascript/checkDeployBlockers/index.js b/.github/actions/javascript/checkDeployBlockers/index.js index 8e10f8b1d8b6..a83cdd2b71fc 100644 --- a/.github/actions/javascript/checkDeployBlockers/index.js +++ b/.github/actions/javascript/checkDeployBlockers/index.js @@ -10,7 +10,7 @@ const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); const CONST = __nccwpck_require__(4097); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); const run = function () { const issueNumber = Number(core.getInput('ISSUE_NUMBER', {required: true})); @@ -107,557 +107,454 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); + if (options && options.trimWhitespace === false) { + return val; } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + finally { + endGroup(); } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); - } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); } - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map /***/ }), -/***/ 7351: +/***/ 717: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +// For internal use, subject to change. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -678,81 +575,130 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); const os = __importStar(__nccwpck_require__(2037)); +const uuid_1 = __nccwpck_require__(5840); const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); } -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; } -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.result.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } } -//# sourceMappingURL=command.js.map +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map /***/ }), -/***/ 2186: +/***/ 2981: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -776,6 +722,52 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -786,465 +778,390 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } /** - * A code indicating that the action was successful + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path */ - ExitCode[ExitCode["Success"] = 0] = "Success"; + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } /** - * A code indicating that the action was a failure + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); } - else { - command_1.issueCommand('add-path', {}, inputPath); + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; } - if (options && options.trimWhitespace === false) { - return val; + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; } - return inputs.map(input => input.trim()); -} -exports.getMultilineInput = getMultilineInput; -/** - * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. - * Support boolean input list: `true | True | TRUE | false | False | FALSE` . - * The return value is also in boolean type. - * ref: https://yaml.org/spec/1.2/spec.html#id2804923 - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns boolean - */ -function getBooleanInput(name, options) { - const trueValue = ['true', 'True', 'TRUE']; - const falseValue = ['false', 'False', 'FALSE']; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + - `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); -} -exports.getBooleanInput = getBooleanInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - const filePath = process.env['GITHUB_OUTPUT'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; } - process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. - * - */ -function setCommandEcho(enabled) { - command_1.issue('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function error(message, properties = {}) { - command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.error = error; -/** - * Adds a warning issue - * @param message warning issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function warning(message, properties = {}) { - command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.warning = warning; -/** - * Adds a notice issue - * @param message notice issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function notice(message, properties = {}) { - command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.notice = notice; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); -} -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - command_1.issue('group', name); -} -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - command_1.issue('endgroup'); -} -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); -} -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function saveState(name, value) { - const filePath = process.env['GITHUB_STATE'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); } - command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); -} -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; -} -exports.getState = getState; -function getIDToken(aud) { - return __awaiter(this, void 0, void 0, function* () { - return yield oidc_utils_1.OidcClient.getIDToken(aud); - }); } -exports.getIDToken = getIDToken; -/** - * Summary exports - */ -var summary_1 = __nccwpck_require__(1327); -Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); -/** - * @deprecated use core.summary - */ -var summary_2 = __nccwpck_require__(1327); -Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +const _summary = new Summary(); /** - * Path exports + * @deprecated use `core.summary` */ -var path_utils_1 = __nccwpck_require__(2981); -Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); -Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); -Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); -//# sourceMappingURL=core.js.map +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map /***/ }), -/***/ 717: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 5278: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -// For internal use, subject to change. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ -const fs = __importStar(__nccwpck_require__(7147)); -const os = __importStar(__nccwpck_require__(2037)); -const uuid_1 = __nccwpck_require__(5840); -const utils_1 = __nccwpck_require__(5278); -function issueFileCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; - if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; } - if (!fs.existsSync(filePath)) { - throw new Error(`Missing file at path: ${filePath}`); + else if (typeof input === 'string' || input instanceof String) { + return input; } - fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { - encoding: 'utf8' - }); + return JSON.stringify(input); } -exports.issueFileCommand = issueFileCommand; -function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - const convertedValue = utils_1.toCommandValue(value); - // These should realistically never happen, but just in case someone finds a - // way to exploit uuid generation let's not allow keys or values that contain - // the delimiter. - if (key.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); - } - if (convertedValue.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; } - return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; } -exports.prepareKeyValueMessage = prepareKeyValueMessage; -//# sourceMappingURL=file-command.js.map +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 8041: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 4087: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.OidcClient = void 0; -const http_client_1 = __nccwpck_require__(6255); -const auth_1 = __nccwpck_require__(5526); -const core_1 = __nccwpck_require__(2186); -class OidcClient { - static createHttpClient(allowRetry = true, maxRetry = 10) { - const requestOptions = { - allowRetries: allowRetry, - maxRetries: maxRetry - }; - return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); - } - static getRequestToken() { - const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; - if (!token) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); - } - return token; - } - static getIDTokenUrl() { - const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; - if (!runtimeUrl) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); +exports.Context = void 0; +const fs_1 = __nccwpck_require__(7147); +const os_1 = __nccwpck_require__(2037); +class Context { + /** + * Hydrate the context from the environment + */ + constructor() { + var _a, _b, _c; + this.payload = {}; + if (process.env.GITHUB_EVENT_PATH) { + if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { + this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); + } + else { + const path = process.env.GITHUB_EVENT_PATH; + process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); + } } - return runtimeUrl; + this.eventName = process.env.GITHUB_EVENT_NAME; + this.sha = process.env.GITHUB_SHA; + this.ref = process.env.GITHUB_REF; + this.workflow = process.env.GITHUB_WORKFLOW; + this.action = process.env.GITHUB_ACTION; + this.actor = process.env.GITHUB_ACTOR; + this.job = process.env.GITHUB_JOB; + this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); + this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); + this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; + this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; + this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; } - static getCall(id_token_url) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const httpclient = OidcClient.createHttpClient(); - const res = yield httpclient - .getJson(id_token_url) - .catch(error => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n - Error Message: ${error.result.message}`); - }); - const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; - if (!id_token) { - throw new Error('Response json body do not have ID Token field'); - } - return id_token; - }); + get issue() { + const payload = this.payload; + return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); } - static getIDToken(audience) { - return __awaiter(this, void 0, void 0, function* () { - try { - // New ID Token is requested from action service - let id_token_url = OidcClient.getIDTokenUrl(); - if (audience) { - const encodedAudience = encodeURIComponent(audience); - id_token_url = `${id_token_url}&audience=${encodedAudience}`; - } - core_1.debug(`ID token url is ${id_token_url}`); - const id_token = yield OidcClient.getCall(id_token_url); - core_1.setSecret(id_token); - return id_token; - } - catch (error) { - throw new Error(`Error message: ${error.message}`); - } - }); + get repo() { + if (process.env.GITHUB_REPOSITORY) { + const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); + return { owner, repo }; + } + if (this.payload.repository) { + return { + owner: this.payload.repository.owner.login, + repo: this.payload.repository.name + }; + } + throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); } } -exports.OidcClient = OidcClient; -//# sourceMappingURL=oidc-utils.js.map +exports.Context = Context; +//# sourceMappingURL=context.js.map /***/ }), -/***/ 2981: +/***/ 7914: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -1269,822 +1186,359 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; -const path = __importStar(__nccwpck_require__(1017)); -/** - * toPosixPath converts the given path to the posix form. On Windows, \\ will be - * replaced with /. - * - * @param pth. Path to transform. - * @return string Posix path. - */ -function toPosixPath(pth) { - return pth.replace(/[\\]/g, '/'); +exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; +const httpClient = __importStar(__nccwpck_require__(6255)); +function getAuthString(token, options) { + if (!token && !options.auth) { + throw new Error('Parameter token or opts.auth is required'); + } + else if (token && options.auth) { + throw new Error('Parameters token and opts.auth may not both be specified'); + } + return typeof options.auth === 'string' ? options.auth : `token ${token}`; } -exports.toPosixPath = toPosixPath; -/** - * toWin32Path converts the given path to the win32 form. On Linux, / will be - * replaced with \\. - * - * @param pth. Path to transform. - * @return string Win32 path. - */ -function toWin32Path(pth) { - return pth.replace(/[/]/g, '\\'); +exports.getAuthString = getAuthString; +function getProxyAgent(destinationUrl) { + const hc = new httpClient.HttpClient(); + return hc.getAgent(destinationUrl); } -exports.toWin32Path = toWin32Path; -/** - * toPlatformPath converts the given path to a platform-specific path. It does - * this by replacing instances of / and \ with the platform-specific path - * separator. - * - * @param pth The path to platformize. - * @return string The platform-specific path. - */ -function toPlatformPath(pth) { - return pth.replace(/[/\\]/g, path.sep); +exports.getProxyAgent = getProxyAgent; +function getApiBaseUrl() { + return process.env['GITHUB_API_URL'] || 'https://api.github.com'; } -exports.toPlatformPath = toPlatformPath; -//# sourceMappingURL=path-utils.js.map +exports.getApiBaseUrl = getApiBaseUrl; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 1327: +/***/ 3030: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; -const os_1 = __nccwpck_require__(2037); -const fs_1 = __nccwpck_require__(7147); -const { access, appendFile, writeFile } = fs_1.promises; -exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; -exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; -class Summary { - constructor() { - this._buffer = ''; - } - /** - * Finds the summary file path from the environment, rejects if env var is not found or file does not exist - * Also checks r/w permissions. - * - * @returns step summary file path - */ - filePath() { - return __awaiter(this, void 0, void 0, function* () { - if (this._filePath) { - return this._filePath; - } - const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; - if (!pathFromEnv) { - throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); - } - try { - yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); - } - catch (_a) { - throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); - } - this._filePath = pathFromEnv; - return this._filePath; - }); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const Utils = __importStar(__nccwpck_require__(7914)); +// octokit + plugins +const core_1 = __nccwpck_require__(8525); +const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); +const plugin_paginate_rest_1 = __nccwpck_require__(8945); +exports.context = new Context.Context(); +const baseUrl = Utils.getApiBaseUrl(); +exports.defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) } - /** - * Wraps content in an HTML tag, adding any HTML attributes - * - * @param {string} tag HTML tag to wrap - * @param {string | null} content content within the tag - * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add - * - * @returns {string} content wrapped in HTML element - */ - wrap(tag, content, attrs = {}) { - const htmlAttrs = Object.entries(attrs) - .map(([key, value]) => ` ${key}="${value}"`) - .join(''); - if (!content) { - return `<${tag}${htmlAttrs}>`; - } - return `<${tag}${htmlAttrs}>${content}`; +}; +exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); +/** + * Convience function to correctly format Octokit Options to pass into the constructor. + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +function getOctokitOptions(token, options) { + const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller + // Auth + const auth = Utils.getAuthString(token, opts); + if (auth) { + opts.auth = auth; } - /** - * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. - * - * @param {SummaryWriteOptions} [options] (optional) options for write operation - * - * @returns {Promise} summary instance - */ - write(options) { - return __awaiter(this, void 0, void 0, function* () { - const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); - const filePath = yield this.filePath(); - const writeFunc = overwrite ? writeFile : appendFile; - yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); - return this.emptyBuffer(); - }); + return opts; +} +exports.getOctokitOptions = getOctokitOptions; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 673: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; +const REGEX_IS_INSTALLATION = /^ghs_/; +const REGEX_IS_USER_TO_SERVER = /^ghu_/; +async function auth(token) { + const isApp = token.split(/\./).length === 3; + const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); + const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); + const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; + return { + type: "token", + token: token, + tokenType + }; +} + +/** + * Prefix token for usage in the Authorization header + * + * @param token OAuth token or JSON Web Token + */ +function withAuthorizationPrefix(token) { + if (token.split(/\./).length === 3) { + return `bearer ${token}`; + } + + return `token ${token}`; +} + +async function hook(token, request, route, parameters) { + const endpoint = request.endpoint.merge(route, parameters); + endpoint.headers.authorization = withAuthorizationPrefix(token); + return request(endpoint); +} + +const createTokenAuth = function createTokenAuth(token) { + if (!token) { + throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); + } + + if (typeof token !== "string") { + throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); + } + + token = token.replace(/^(token|bearer) +/i, ""); + return Object.assign(auth.bind(null, token), { + hook: hook.bind(null, token) + }); +}; + +exports.createTokenAuth = createTokenAuth; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 8525: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var universalUserAgent = __nccwpck_require__(5030); +var beforeAfterHook = __nccwpck_require__(3682); +var request = __nccwpck_require__(9353); +var graphql = __nccwpck_require__(6422); +var authToken = __nccwpck_require__(673); + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; } - /** - * Clears the summary buffer and wipes the summary file - * - * @returns {Summary} summary instance - */ - clear() { - return __awaiter(this, void 0, void 0, function* () { - return this.emptyBuffer().write({ overwrite: true }); - }); + } + + return target; +} + +const VERSION = "3.6.0"; + +const _excluded = ["authStrategy"]; +class Octokit { + constructor(options = {}) { + const hook = new beforeAfterHook.Collection(); + const requestDefaults = { + baseUrl: request.request.endpoint.DEFAULTS.baseUrl, + headers: {}, + request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type + hook: hook.bind(null, "request") + }), + mediaType: { + previews: [], + format: "" + } + }; // prepend default user agent with `options.userAgent` if set + + requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); + + if (options.baseUrl) { + requestDefaults.baseUrl = options.baseUrl; } - /** - * Returns the current summary buffer as a string - * - * @returns {string} string of summary buffer - */ - stringify() { - return this._buffer; - } - /** - * If the summary buffer is empty - * - * @returns {boolen} true if the buffer is empty - */ - isEmptyBuffer() { - return this._buffer.length === 0; - } - /** - * Resets the summary buffer without writing to summary file - * - * @returns {Summary} summary instance - */ - emptyBuffer() { - this._buffer = ''; - return this; - } - /** - * Adds raw text to the summary buffer - * - * @param {string} text content to add - * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) - * - * @returns {Summary} summary instance - */ - addRaw(text, addEOL = false) { - this._buffer += text; - return addEOL ? this.addEOL() : this; - } - /** - * Adds the operating system-specific end-of-line marker to the buffer - * - * @returns {Summary} summary instance - */ - addEOL() { - return this.addRaw(os_1.EOL); - } - /** - * Adds an HTML codeblock to the summary buffer - * - * @param {string} code content to render within fenced code block - * @param {string} lang (optional) language to syntax highlight code - * - * @returns {Summary} summary instance - */ - addCodeBlock(code, lang) { - const attrs = Object.assign({}, (lang && { lang })); - const element = this.wrap('pre', this.wrap('code', code), attrs); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML list to the summary buffer - * - * @param {string[]} items list of items to render - * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) - * - * @returns {Summary} summary instance - */ - addList(items, ordered = false) { - const tag = ordered ? 'ol' : 'ul'; - const listItems = items.map(item => this.wrap('li', item)).join(''); - const element = this.wrap(tag, listItems); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML table to the summary buffer - * - * @param {SummaryTableCell[]} rows table rows - * - * @returns {Summary} summary instance - */ - addTable(rows) { - const tableBody = rows - .map(row => { - const cells = row - .map(cell => { - if (typeof cell === 'string') { - return this.wrap('td', cell); - } - const { header, data, colspan, rowspan } = cell; - const tag = header ? 'th' : 'td'; - const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); - return this.wrap(tag, data, attrs); - }) - .join(''); - return this.wrap('tr', cells); - }) - .join(''); - const element = this.wrap('table', tableBody); - return this.addRaw(element).addEOL(); - } - /** - * Adds a collapsable HTML details element to the summary buffer - * - * @param {string} label text for the closed state - * @param {string} content collapsable content - * - * @returns {Summary} summary instance - */ - addDetails(label, content) { - const element = this.wrap('details', this.wrap('summary', label) + content); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML image tag to the summary buffer - * - * @param {string} src path to the image you to embed - * @param {string} alt text description of the image - * @param {SummaryImageOptions} options (optional) addition image attributes - * - * @returns {Summary} summary instance - */ - addImage(src, alt, options) { - const { width, height } = options || {}; - const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); - const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML section heading element - * - * @param {string} text heading text - * @param {number | string} [level=1] (optional) the heading level, default: 1 - * - * @returns {Summary} summary instance - */ - addHeading(text, level) { - const tag = `h${level}`; - const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) - ? tag - : 'h1'; - const element = this.wrap(allowedTag, text); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML thematic break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addSeparator() { - const element = this.wrap('hr', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML line break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addBreak() { - const element = this.wrap('br', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML blockquote to the summary buffer - * - * @param {string} text quote text - * @param {string} cite (optional) citation url - * - * @returns {Summary} summary instance - */ - addQuote(text, cite) { - const attrs = Object.assign({}, (cite && { cite })); - const element = this.wrap('blockquote', text, attrs); - return this.addRaw(element).addEOL(); + + if (options.previews) { + requestDefaults.mediaType.previews = options.previews; } - /** - * Adds an HTML anchor tag to the summary buffer - * - * @param {string} text link text/content - * @param {string} href hyperlink - * - * @returns {Summary} summary instance - */ - addLink(text, href) { - const element = this.wrap('a', text, { href }); - return this.addRaw(element).addEOL(); + + if (options.timeZone) { + requestDefaults.headers["time-zone"] = options.timeZone; } -} -const _summary = new Summary(); -/** - * @deprecated use `core.summary` - */ -exports.markdownSummary = _summary; -exports.summary = _summary; -//# sourceMappingURL=summary.js.map -/***/ }), + this.request = request.request.defaults(requestDefaults); + this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); + this.log = Object.assign({ + debug: () => {}, + info: () => {}, + warn: console.warn.bind(console), + error: console.error.bind(console) + }, options.log); + this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance + // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. + // (2) If only `options.auth` is set, use the default token authentication strategy. + // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. + // TODO: type `options.auth` based on `options.authStrategy`. -/***/ 5278: -/***/ ((__unused_webpack_module, exports) => { + if (!options.authStrategy) { + if (!options.auth) { + // (1) + this.auth = async () => ({ + type: "unauthenticated" + }); + } else { + // (2) + const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ -"use strict"; + hook.wrap("request", auth.hook); + this.auth = auth; + } + } else { + const { + authStrategy + } = options, + otherOptions = _objectWithoutProperties(options, _excluded); -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toCommandProperties = exports.toCommandValue = void 0; -/** - * Sanitizes an input into a string so it can be passed into issueCommand safely - * @param input input to sanitize into a string - */ -function toCommandValue(input) { - if (input === null || input === undefined) { - return ''; - } - else if (typeof input === 'string' || input instanceof String) { - return input; - } - return JSON.stringify(input); -} -exports.toCommandValue = toCommandValue; -/** - * - * @param annotationProperties - * @returns The command properties to send with the actual annotation command - * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 - */ -function toCommandProperties(annotationProperties) { - if (!Object.keys(annotationProperties).length) { - return {}; - } - return { - title: annotationProperties.title, - file: annotationProperties.file, - line: annotationProperties.startLine, - endLine: annotationProperties.endLine, - col: annotationProperties.startColumn, - endColumn: annotationProperties.endColumn - }; -} -exports.toCommandProperties = toCommandProperties; -//# sourceMappingURL=utils.js.map + const auth = authStrategy(Object.assign({ + request: this.request, + log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. + octokit: this, + octokitOptions: otherOptions + }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ -/***/ }), + hook.wrap("request", auth.hook); + this.auth = auth; + } // apply plugins + // https://stackoverflow.com/a/16345172 -/***/ 4087: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; + const classConstructor = this.constructor; + classConstructor.plugins.forEach(plugin => { + Object.assign(this, plugin(this, options)); + }); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Context = void 0; -const fs_1 = __nccwpck_require__(7147); -const os_1 = __nccwpck_require__(2037); -class Context { - /** - * Hydrate the context from the environment - */ - constructor() { - var _a, _b, _c; - this.payload = {}; - if (process.env.GITHUB_EVENT_PATH) { - if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { - this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); - } - else { - const path = process.env.GITHUB_EVENT_PATH; - process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); - } - } - this.eventName = process.env.GITHUB_EVENT_NAME; - this.sha = process.env.GITHUB_SHA; - this.ref = process.env.GITHUB_REF; - this.workflow = process.env.GITHUB_WORKFLOW; - this.action = process.env.GITHUB_ACTION; - this.actor = process.env.GITHUB_ACTOR; - this.job = process.env.GITHUB_JOB; - this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); - this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); - this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; - this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; - this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; - } - get issue() { - const payload = this.payload; - return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); - } - get repo() { - if (process.env.GITHUB_REPOSITORY) { - const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); - return { owner, repo }; - } - if (this.payload.repository) { - return { - owner: this.payload.repository.owner.login, - repo: this.payload.repository.name - }; + static defaults(defaults) { + const OctokitWithDefaults = class extends this { + constructor(...args) { + const options = args[0] || {}; + + if (typeof defaults === "function") { + super(defaults(options)); + return; } - throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); - } -} -exports.Context = Context; -//# sourceMappingURL=context.js.map -/***/ }), + super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { + userAgent: `${options.userAgent} ${defaults.userAgent}` + } : null)); + } -/***/ 7914: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + }; + return OctokitWithDefaults; + } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; -const httpClient = __importStar(__nccwpck_require__(6255)); -function getAuthString(token, options) { - if (!token && !options.auth) { - throw new Error('Parameter token or opts.auth is required'); - } - else if (token && options.auth) { - throw new Error('Parameters token and opts.auth may not both be specified'); - } - return typeof options.auth === 'string' ? options.auth : `token ${token}`; -} -exports.getAuthString = getAuthString; -function getProxyAgent(destinationUrl) { - const hc = new httpClient.HttpClient(); - return hc.getAgent(destinationUrl); -} -exports.getProxyAgent = getProxyAgent; -function getApiBaseUrl() { - return process.env['GITHUB_API_URL'] || 'https://api.github.com'; -} -exports.getApiBaseUrl = getApiBaseUrl; -//# sourceMappingURL=utils.js.map + static plugin(...newPlugins) { + var _a; -/***/ }), + const currentPlugins = this.plugins; + const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); + return NewOctokit; + } -/***/ 3030: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +} +Octokit.VERSION = VERSION; +Octokit.plugins = []; -"use strict"; +exports.Octokit = Octokit; +//# sourceMappingURL=index.js.map -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(4087)); -const Utils = __importStar(__nccwpck_require__(7914)); -// octokit + plugins -const core_1 = __nccwpck_require__(8525); -const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); -const plugin_paginate_rest_1 = __nccwpck_require__(8945); -exports.context = new Context.Context(); -const baseUrl = Utils.getApiBaseUrl(); -exports.defaults = { - baseUrl, - request: { - agent: Utils.getProxyAgent(baseUrl) - } -}; -exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); -/** - * Convience function to correctly format Octokit Options to pass into the constructor. - * - * @param token the repo PAT or GITHUB_TOKEN - * @param options other options to set - */ -function getOctokitOptions(token, options) { - const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller - // Auth - const auth = Utils.getAuthString(token, opts); - if (auth) { - opts.auth = auth; - } - return opts; -} -exports.getOctokitOptions = getOctokitOptions; -//# sourceMappingURL=utils.js.map /***/ }), -/***/ 673: -/***/ ((__unused_webpack_module, exports) => { +/***/ 8713: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; -const REGEX_IS_INSTALLATION = /^ghs_/; -const REGEX_IS_USER_TO_SERVER = /^ghu_/; -async function auth(token) { - const isApp = token.split(/\./).length === 3; - const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); - const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); - const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; - return { - type: "token", - token: token, - tokenType - }; -} +var isPlainObject = __nccwpck_require__(3287); +var universalUserAgent = __nccwpck_require__(5030); -/** - * Prefix token for usage in the Authorization header - * - * @param token OAuth token or JSON Web Token - */ -function withAuthorizationPrefix(token) { - if (token.split(/\./).length === 3) { - return `bearer ${token}`; +function lowercaseKeys(object) { + if (!object) { + return {}; } - return `token ${token}`; -} - -async function hook(token, request, route, parameters) { - const endpoint = request.endpoint.merge(route, parameters); - endpoint.headers.authorization = withAuthorizationPrefix(token); - return request(endpoint); -} - -const createTokenAuth = function createTokenAuth(token) { - if (!token) { - throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); - } - - if (typeof token !== "string") { - throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); - } - - token = token.replace(/^(token|bearer) +/i, ""); - return Object.assign(auth.bind(null, token), { - hook: hook.bind(null, token) - }); -}; - -exports.createTokenAuth = createTokenAuth; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 8525: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -var universalUserAgent = __nccwpck_require__(5030); -var beforeAfterHook = __nccwpck_require__(3682); -var request = __nccwpck_require__(9353); -var graphql = __nccwpck_require__(6422); -var authToken = __nccwpck_require__(673); - -function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; - - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } - - return target; -} - -function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - - var target = _objectWithoutPropertiesLoose(source, excluded); - - var key, i; - - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } - - return target; -} - -const VERSION = "3.6.0"; - -const _excluded = ["authStrategy"]; -class Octokit { - constructor(options = {}) { - const hook = new beforeAfterHook.Collection(); - const requestDefaults = { - baseUrl: request.request.endpoint.DEFAULTS.baseUrl, - headers: {}, - request: Object.assign({}, options.request, { - // @ts-ignore internal usage only, no need to type - hook: hook.bind(null, "request") - }), - mediaType: { - previews: [], - format: "" - } - }; // prepend default user agent with `options.userAgent` if set - - requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); - - if (options.baseUrl) { - requestDefaults.baseUrl = options.baseUrl; - } - - if (options.previews) { - requestDefaults.mediaType.previews = options.previews; - } - - if (options.timeZone) { - requestDefaults.headers["time-zone"] = options.timeZone; - } - - this.request = request.request.defaults(requestDefaults); - this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); - this.log = Object.assign({ - debug: () => {}, - info: () => {}, - warn: console.warn.bind(console), - error: console.error.bind(console) - }, options.log); - this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance - // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. - // (2) If only `options.auth` is set, use the default token authentication strategy. - // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. - // TODO: type `options.auth` based on `options.authStrategy`. - - if (!options.authStrategy) { - if (!options.auth) { - // (1) - this.auth = async () => ({ - type: "unauthenticated" - }); - } else { - // (2) - const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } - } else { - const { - authStrategy - } = options, - otherOptions = _objectWithoutProperties(options, _excluded); - - const auth = authStrategy(Object.assign({ - request: this.request, - log: this.log, - // we pass the current octokit instance as well as its constructor options - // to allow for authentication strategies that return a new octokit instance - // that shares the same internal state as the current one. The original - // requirement for this was the "event-octokit" authentication strategy - // of https://github.com/probot/octokit-auth-probot. - octokit: this, - octokitOptions: otherOptions - }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } // apply plugins - // https://stackoverflow.com/a/16345172 - - - const classConstructor = this.constructor; - classConstructor.plugins.forEach(plugin => { - Object.assign(this, plugin(this, options)); - }); - } - - static defaults(defaults) { - const OctokitWithDefaults = class extends this { - constructor(...args) { - const options = args[0] || {}; - - if (typeof defaults === "function") { - super(defaults(options)); - return; - } - - super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { - userAgent: `${options.userAgent} ${defaults.userAgent}` - } : null)); - } - - }; - return OctokitWithDefaults; - } - /** - * Attach a plugin (or many) to your Octokit instance. - * - * @example - * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) - */ - - - static plugin(...newPlugins) { - var _a; - - const currentPlugins = this.plugins; - const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); - return NewOctokit; - } - -} -Octokit.VERSION = VERSION; -Octokit.plugins = []; - -exports.Octokit = Octokit; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 8713: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -var isPlainObject = __nccwpck_require__(3287); -var universalUserAgent = __nccwpck_require__(5030); - -function lowercaseKeys(object) { - if (!object) { - return {}; - } - - return Object.keys(object).reduce((newObj, key) => { - newObj[key.toLowerCase()] = object[key]; - return newObj; - }, {}); + return Object.keys(object).reduce((newObj, key) => { + newObj[key.toLowerCase()] = object[key]; + return newObj; + }, {}); } function mergeDeep(defaults, options) { @@ -4855,3919 +4309,2309 @@ const Endpoints = { }], renameBranch: ["POST /repos/{owner}/{repo}/branches/{branch}/rename"], replaceAllTopics: ["PUT /repos/{owner}/{repo}/topics"], - requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], - setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], - setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { - mapToData: "apps" - }], - setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { - mapToData: "contexts" - }], - setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { - mapToData: "teams" - }], - setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { - mapToData: "users" - }], - testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], - transfer: ["POST /repos/{owner}/{repo}/transfer"], - update: ["PATCH /repos/{owner}/{repo}"], - updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], - updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], - updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], - updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], - updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], + setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], + transfer: ["POST /repos/{owner}/{repo}/transfer"], + update: ["PATCH /repos/{owner}/{repo}"], + updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], + updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], + updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], + updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; + +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +"use strict"; -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = Hash; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; -module.exports = ListCache; + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ }), + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + const req = state.global.key(state.id).schedule(jobOptions, request, options); -module.exports = Map; + if (isGraphQL) { + const res = await req; + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -/***/ }), + return req; +} -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +function routeMatcher(paths) { + // EXAMPLE. For the following paths: -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -module.exports = MapCache; + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ + return new RegExp(regex, "i"); +} -/***/ }), +// @ts-expect-error -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -var root = __nccwpck_require__(9882); +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -/** Built-in value references. */ -var Symbol = root.Symbol; +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -module.exports = Symbol; + if (!enabled) { + return {}; + } + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 4356: -/***/ ((module) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling - while (++index < length) { - result[index] = iteratee(array[index], index, array); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); } - return result; -} -module.exports = arrayMap; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -/***/ }), + events.on("rate-limit", state.onRateLimit); // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -var eq = __nccwpck_require__(1901); + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } + + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + return {}; + }(); + + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; } - } - return -1; + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = assocIndexOf; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5758: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) - var index = 0, - length = path.length; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) } -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +function HookCollection () { + var state = { + registry: {} + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return hook +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return HookCollection() } -module.exports = baseIsNative; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +/***/ 5549: +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +module.exports = addHook; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} -module.exports = baseToString; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4670: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = register; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!options) { + options = {}; + } -var root = __nccwpck_require__(9882); + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -module.exports = coreJsData; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} /***/ }), -/***/ 2085: +/***/ 6819: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - +module.exports = removeHook; -/***/ }), +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + if (index === -1) { + return; + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + state.registry[name].splice(index, 1); } -module.exports = getNative; - /***/ }), -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13452,230 +11296,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js index 4441348a3c36..63398614fd11 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js @@ -40,8 +40,11 @@ async function run() { // Next, we generate the checklist body let checklistBody = ''; + let checklistAssignees = []; if (shouldCreateNewDeployChecklist) { - checklistBody = await GithubUtils.generateStagingDeployCashBody(newVersionTag, _.map(mergedPRs, GithubUtils.getPullRequestURLFromNumber)); + const {issueBody, issueAssignees} = await GithubUtils.generateStagingDeployCashBodyAndAssignees(newVersionTag, _.map(mergedPRs, GithubUtils.getPullRequestURLFromNumber)); + checklistBody = issueBody; + checklistAssignees = issueAssignees; } else { // Generate the updated PR list, preserving the previous state of `isVerified` for existing PRs const PRList = _.reduce( @@ -94,7 +97,7 @@ async function run() { } const didVersionChange = newVersionTag !== currentChecklistData.tag; - checklistBody = await GithubUtils.generateStagingDeployCashBody( + const {issueBody, issueAssignees} = await GithubUtils.generateStagingDeployCashBodyAndAssignees( newVersionTag, _.pluck(PRList, 'url'), _.pluck(_.where(PRList, {isVerified: true}), 'url'), @@ -105,6 +108,8 @@ async function run() { didVersionChange ? false : currentChecklistData.isFirebaseChecked, didVersionChange ? false : currentChecklistData.isGHStatusChecked, ); + checklistBody = issueBody; + checklistAssignees = issueAssignees; } // Finally, create or update the checklist @@ -119,7 +124,7 @@ async function run() { ...defaultPayload, title: `Deploy Checklist: New Expensify ${format(new Date(), CONST.DATE_FORMAT_STRING)}`, labels: [CONST.LABELS.STAGING_DEPLOY], - assignees: [CONST.APPLAUSE_BOT], + assignees: [CONST.APPLAUSE_BOT].concat(checklistAssignees), }); console.log(`Successfully created new StagingDeployCash! 🎉 ${newChecklist.html_url}`); return newChecklist; diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js index 154dacbdc3c3..69eef6cfc7fc 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js @@ -12,7 +12,7 @@ const format = __nccwpck_require__(2168); const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); const CONST = __nccwpck_require__(4097); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); const GitUtils = (__nccwpck_require__(1547)["default"]); async function run() { @@ -49,8 +49,11 @@ async function run() { // Next, we generate the checklist body let checklistBody = ''; + let checklistAssignees = []; if (shouldCreateNewDeployChecklist) { - checklistBody = await GithubUtils.generateStagingDeployCashBody(newVersionTag, _.map(mergedPRs, GithubUtils.getPullRequestURLFromNumber)); + const {issueBody, issueAssignees} = await GithubUtils.generateStagingDeployCashBodyAndAssignees(newVersionTag, _.map(mergedPRs, GithubUtils.getPullRequestURLFromNumber)); + checklistBody = issueBody; + checklistAssignees = issueAssignees; } else { // Generate the updated PR list, preserving the previous state of `isVerified` for existing PRs const PRList = _.reduce( @@ -103,7 +106,7 @@ async function run() { } const didVersionChange = newVersionTag !== currentChecklistData.tag; - checklistBody = await GithubUtils.generateStagingDeployCashBody( + const {issueBody, issueAssignees} = await GithubUtils.generateStagingDeployCashBodyAndAssignees( newVersionTag, _.pluck(PRList, 'url'), _.pluck(_.where(PRList, {isVerified: true}), 'url'), @@ -114,6 +117,8 @@ async function run() { didVersionChange ? false : currentChecklistData.isFirebaseChecked, didVersionChange ? false : currentChecklistData.isGHStatusChecked, ); + checklistBody = issueBody; + checklistAssignees = issueAssignees; } // Finally, create or update the checklist @@ -128,7 +133,7 @@ async function run() { ...defaultPayload, title: `Deploy Checklist: New Expensify ${format(new Date(), CONST.DATE_FORMAT_STRING)}`, labels: [CONST.LABELS.STAGING_DEPLOY], - assignees: [CONST.APPLAUSE_BOT], + assignees: [CONST.APPLAUSE_BOT].concat(checklistAssignees), }); console.log(`Successfully created new StagingDeployCash! 🎉 ${newChecklist.html_url}`); return newChecklist; @@ -179,740 +184,637 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9338: +/***/ ((module) => { + +const replacer = (str) => + ({ + '\\': '\\\\', + '\t': '\\t', + '\n': '\\n', + '\r': '\\r', + '\f': '\\f', + '"': '\\"', + }[str]); + +/** + * Replace any characters in the string that will break JSON.parse for our Git Log output + * + * Solution partly taken from SO user Gabriel Rodríguez Flores 🙇 + * https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading + * + * @param {String} inputString + * @returns {String} + */ +module.exports = function (inputString) { + if (typeof inputString !== 'string') { + throw new TypeError('Input must me of type String'); + } + + // Replace any newlines and escape backslashes + return inputString.replace(/\\|\t|\n|\r|\f|"/g, replacer); +}; + +/***/ }), + +/***/ 8007: +/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { + +"use strict"; +__nccwpck_require__.r(__webpack_exports__); +/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { +/* harmony export */ "MAX_INCREMENTS": () => (/* binding */ MAX_INCREMENTS), +/* harmony export */ "SEMANTIC_VERSION_LEVELS": () => (/* binding */ SEMANTIC_VERSION_LEVELS), +/* harmony export */ "getPreviousVersion": () => (/* binding */ getPreviousVersion), +/* harmony export */ "getVersionNumberFromString": () => (/* binding */ getVersionNumberFromString), +/* harmony export */ "getVersionStringFromNumber": () => (/* binding */ getVersionStringFromNumber), +/* harmony export */ "incrementMinor": () => (/* binding */ incrementMinor), +/* harmony export */ "incrementPatch": () => (/* binding */ incrementPatch), +/* harmony export */ "incrementVersion": () => (/* binding */ incrementVersion) +/* harmony export */ }); const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +const SEMANTIC_VERSION_LEVELS = { + MAJOR: 'MAJOR', + MINOR: 'MINOR', + PATCH: 'PATCH', + BUILD: 'BUILD', +}; +const MAX_INCREMENTS = 99; /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Transforms a versions string into a number + * + * @param {String} versionString + * @returns {Array} */ -const POLL_RATE = 10000; +const getVersionNumberFromString = (versionString) => { + const [version, build] = versionString.split('-'); + const [major, minor, patch] = _.map(version.split('.'), (n) => Number(n)); -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); + return [major, minor, patch, Number.isInteger(Number(build)) ? Number(build) : 0]; +}; - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } +/** + * Transforms version numbers components into a version string + * + * @param {Number} major + * @param {Number} minor + * @param {Number} patch + * @param {Number} [build] + * @returns {String} + */ +const getVersionStringFromNumber = (major, minor, patch, build = 0) => `${major}.${minor}.${patch}-${build}`; - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; +/** + * Increments a minor version + * + * @param {Number} major + * @param {Number} minor + * @returns {String} + */ +const incrementMinor = (major, minor) => { + if (minor < MAX_INCREMENTS) { + return getVersionStringFromNumber(major, minor + 1, 0, 0); } - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; - } - this.initOctokit(); - return this.internalOctokit.graphql; + return getVersionStringFromNumber(major + 1, 0, 0, 0); +}; + +/** + * Increments a Patch version + * + * @param {Number} major + * @param {Number} minor + * @param {Number} patch + * @returns {String} + */ +const incrementPatch = (major, minor, patch) => { + if (patch < MAX_INCREMENTS) { + return getVersionStringFromNumber(major, minor, patch + 1, 0); } + return incrementMinor(major, minor); +}; - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; - } - this.initOctokit(); - return this.internalOctokit.paginate; +/** + * Increments a build version + * + * @param {String} version + * @param {String} level + * @returns {String} + */ +const incrementVersion = (version, level) => { + const [major, minor, patch, build] = getVersionNumberFromString(version); + + // Majors will always be incremented + if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { + return getVersionStringFromNumber(major + 1, 0, 0, 0); } - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } + if (level === SEMANTIC_VERSION_LEVELS.MINOR) { + return incrementMinor(major, minor); + } - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } + if (level === SEMANTIC_VERSION_LEVELS.PATCH) { + return incrementPatch(major, minor, patch); + } - return this.getStagingDeployCashData(data[0]); - }); + if (build < MAX_INCREMENTS) { + return getVersionStringFromNumber(major, minor, patch, build + 1); } - /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} - */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); + return incrementPatch(major, minor, patch); +}; + +/** + * @param {String} currentVersion + * @param {String} level + * @returns {String} + */ +function getPreviousVersion(currentVersion, level) { + const [major, minor, patch, build] = getVersionNumberFromString(currentVersion); + + if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { + if (major === 1) { + return getVersionStringFromNumber(1, 0, 0, 0); } + return getVersionStringFromNumber(major - 1, 0, 0, 0); } - /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] - */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; + if (level === SEMANTIC_VERSION_LEVELS.MINOR) { + if (minor === 0) { + return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MAJOR); } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + return getVersionStringFromNumber(major, minor - 1, 0, 0); } - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; + if (level === SEMANTIC_VERSION_LEVELS.PATCH) { + if (patch === 0) { + return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MINOR); } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); + return getVersionStringFromNumber(major, minor, patch - 1, 0); } - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); + if (build === 0) { + return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.PATCH); } + return getVersionStringFromNumber(major, minor, patch, build - 1); +} - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } +/***/ }), - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; +"use strict"; - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } +/***/ }), - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} + * A code indicating that the action was successful */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} + * A code indicating that the action was a failure */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + else { + command_1.issueCommand('add-path', {}, inputPath); } + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; } - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 9338: -/***/ ((module) => { - -const replacer = (str) => - ({ - '\\': '\\\\', - '\t': '\\t', - '\n': '\\n', - '\r': '\\r', - '\f': '\\f', - '"': '\\"', - }[str]); - +exports.addPath = addPath; /** - * Replace any characters in the string that will break JSON.parse for our Git Log output - * - * Solution partly taken from SO user Gabriel Rodríguez Flores 🙇 - * https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. * - * @param {String} inputString - * @returns {String} + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string */ -module.exports = function (inputString) { - if (typeof inputString !== 'string') { - throw new TypeError('Input must me of type String'); +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - // Replace any newlines and escape backslashes - return inputString.replace(/\\|\t|\n|\r|\f|"/g, replacer); -}; - - -/***/ }), - -/***/ 8007: -/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { - -"use strict"; -__nccwpck_require__.r(__webpack_exports__); -/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { -/* harmony export */ "MAX_INCREMENTS": () => (/* binding */ MAX_INCREMENTS), -/* harmony export */ "SEMANTIC_VERSION_LEVELS": () => (/* binding */ SEMANTIC_VERSION_LEVELS), -/* harmony export */ "getPreviousVersion": () => (/* binding */ getPreviousVersion), -/* harmony export */ "getVersionNumberFromString": () => (/* binding */ getVersionNumberFromString), -/* harmony export */ "getVersionStringFromNumber": () => (/* binding */ getVersionStringFromNumber), -/* harmony export */ "incrementMinor": () => (/* binding */ incrementMinor), -/* harmony export */ "incrementPatch": () => (/* binding */ incrementPatch), -/* harmony export */ "incrementVersion": () => (/* binding */ incrementVersion) -/* harmony export */ }); -const _ = __nccwpck_require__(5067); - -const SEMANTIC_VERSION_LEVELS = { - MAJOR: 'MAJOR', - MINOR: 'MINOR', - PATCH: 'PATCH', - BUILD: 'BUILD', -}; -const MAX_INCREMENTS = 99; - + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); +} +exports.getInput = getInput; /** - * Transforms a versions string into a number + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] * - * @param {String} versionString - * @returns {Array} */ -const getVersionNumberFromString = (versionString) => { - const [version, build] = versionString.split('-'); - const [major, minor, patch] = _.map(version.split('.'), (n) => Number(n)); - - return [major, minor, patch, Number.isInteger(Number(build)) ? Number(build) : 0]; -}; - +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; /** - * Transforms version numbers components into a version string + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 * - * @param {Number} major - * @param {Number} minor - * @param {Number} patch - * @param {Number} [build] - * @returns {String} + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean */ -const getVersionStringFromNumber = (major, minor, patch, build = 0) => `${major}.${minor}.${patch}-${build}`; - +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; /** - * Increments a minor version + * Sets the value of an output. * - * @param {Number} major - * @param {Number} minor - * @returns {String} + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify */ -const incrementMinor = (major, minor) => { - if (minor < MAX_INCREMENTS) { - return getVersionStringFromNumber(major, minor + 1, 0, 0); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); } - - return getVersionStringFromNumber(major + 1, 0, 0, 0); -}; - + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; /** - * Increments a Patch version + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. * - * @param {Number} major - * @param {Number} minor - * @param {Number} patch - * @returns {String} */ -const incrementPatch = (major, minor, patch) => { - if (patch < MAX_INCREMENTS) { - return getVersionStringFromNumber(major, minor, patch + 1, 0); - } - return incrementMinor(major, minor); -}; - +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- /** - * Increments a build version + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. * - * @param {String} version - * @param {String} level - * @returns {String} + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group */ -const incrementVersion = (version, level) => { - const [major, minor, patch, build] = getVersionNumberFromString(version); - - // Majors will always be incremented - if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { - return getVersionStringFromNumber(major + 1, 0, 0, 0); - } - - if (level === SEMANTIC_VERSION_LEVELS.MINOR) { - return incrementMinor(major, minor); - } - - if (level === SEMANTIC_VERSION_LEVELS.PATCH) { - return incrementPatch(major, minor, patch); - } - - if (build < MAX_INCREMENTS) { - return getVersionStringFromNumber(major, minor, patch, build + 1); - } - - return incrementPatch(major, minor, patch); -}; - +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; /** - * @param {String} currentVersion - * @param {String} level - * @returns {String} + * End an output group. */ -function getPreviousVersion(currentVersion, level) { - const [major, minor, patch, build] = getVersionNumberFromString(currentVersion); - - if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { - if (major === 1) { - return getVersionStringFromNumber(1, 0, 0, 0); - } - return getVersionStringFromNumber(major - 1, 0, 0, 0); - } - - if (level === SEMANTIC_VERSION_LEVELS.MINOR) { - if (minor === 0) { - return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MAJOR); +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); } - return getVersionStringFromNumber(major, minor - 1, 0, 0); - } - - if (level === SEMANTIC_VERSION_LEVELS.PATCH) { - if (patch === 0) { - return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MINOR); + finally { + endGroup(); } - return getVersionStringFromNumber(major, minor, patch - 1, 0); - } - - if (build === 0) { - return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.PATCH); + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); } - return getVersionStringFromNumber(major, minor, patch, build - 1); + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); } - - - +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map /***/ }), -/***/ 7351: +/***/ 717: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +// For internal use, subject to change. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -933,81 +835,130 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); const os = __importStar(__nccwpck_require__(2037)); +const uuid_1 = __nccwpck_require__(5840); const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); + } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); } -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; } -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); } - this.command = command; - this.properties = properties; - this.message = message; + return token; } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.result.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); } } -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map /***/ }), -/***/ 2186: +/***/ 2981: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -1031,6 +982,52 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -1041,465 +1038,390 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } /** - * A code indicating that the action was successful + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path */ - ExitCode[ExitCode["Success"] = 0] = "Success"; + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } /** - * A code indicating that the action was a failure + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); } - else { - command_1.issueCommand('add-path', {}, inputPath); + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; } - if (options && options.trimWhitespace === false) { - return val; + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; } - return inputs.map(input => input.trim()); -} -exports.getMultilineInput = getMultilineInput; -/** - * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. - * Support boolean input list: `true | True | TRUE | false | False | FALSE` . - * The return value is also in boolean type. - * ref: https://yaml.org/spec/1.2/spec.html#id2804923 - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns boolean - */ -function getBooleanInput(name, options) { - const trueValue = ['true', 'True', 'TRUE']; - const falseValue = ['false', 'False', 'FALSE']; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + - `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); -} -exports.getBooleanInput = getBooleanInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - const filePath = process.env['GITHUB_OUTPUT'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; } - process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. - * - */ -function setCommandEcho(enabled) { - command_1.issue('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function error(message, properties = {}) { - command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.error = error; -/** - * Adds a warning issue - * @param message warning issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function warning(message, properties = {}) { - command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.warning = warning; -/** - * Adds a notice issue - * @param message notice issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function notice(message, properties = {}) { - command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.notice = notice; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); -} -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - command_1.issue('group', name); -} -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - command_1.issue('endgroup'); -} -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); -} -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function saveState(name, value) { - const filePath = process.env['GITHUB_STATE'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); } - command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); -} -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; -} -exports.getState = getState; -function getIDToken(aud) { - return __awaiter(this, void 0, void 0, function* () { - return yield oidc_utils_1.OidcClient.getIDToken(aud); - }); } -exports.getIDToken = getIDToken; -/** - * Summary exports - */ -var summary_1 = __nccwpck_require__(1327); -Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); -/** - * @deprecated use core.summary - */ -var summary_2 = __nccwpck_require__(1327); -Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +const _summary = new Summary(); /** - * Path exports + * @deprecated use `core.summary` */ -var path_utils_1 = __nccwpck_require__(2981); -Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); -Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); -Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); -//# sourceMappingURL=core.js.map +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map /***/ }), -/***/ 717: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 5278: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -// For internal use, subject to change. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ -const fs = __importStar(__nccwpck_require__(7147)); -const os = __importStar(__nccwpck_require__(2037)); -const uuid_1 = __nccwpck_require__(5840); -const utils_1 = __nccwpck_require__(5278); -function issueFileCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; - if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; } - if (!fs.existsSync(filePath)) { - throw new Error(`Missing file at path: ${filePath}`); + else if (typeof input === 'string' || input instanceof String) { + return input; } - fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { - encoding: 'utf8' - }); + return JSON.stringify(input); } -exports.issueFileCommand = issueFileCommand; -function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - const convertedValue = utils_1.toCommandValue(value); - // These should realistically never happen, but just in case someone finds a - // way to exploit uuid generation let's not allow keys or values that contain - // the delimiter. - if (key.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); - } - if (convertedValue.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; } - return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; } -exports.prepareKeyValueMessage = prepareKeyValueMessage; -//# sourceMappingURL=file-command.js.map +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 8041: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 4087: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.OidcClient = void 0; -const http_client_1 = __nccwpck_require__(6255); -const auth_1 = __nccwpck_require__(5526); -const core_1 = __nccwpck_require__(2186); -class OidcClient { - static createHttpClient(allowRetry = true, maxRetry = 10) { - const requestOptions = { - allowRetries: allowRetry, - maxRetries: maxRetry - }; - return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); - } - static getRequestToken() { - const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; - if (!token) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); - } - return token; - } - static getIDTokenUrl() { - const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; - if (!runtimeUrl) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); +exports.Context = void 0; +const fs_1 = __nccwpck_require__(7147); +const os_1 = __nccwpck_require__(2037); +class Context { + /** + * Hydrate the context from the environment + */ + constructor() { + var _a, _b, _c; + this.payload = {}; + if (process.env.GITHUB_EVENT_PATH) { + if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { + this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); + } + else { + const path = process.env.GITHUB_EVENT_PATH; + process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); + } } - return runtimeUrl; + this.eventName = process.env.GITHUB_EVENT_NAME; + this.sha = process.env.GITHUB_SHA; + this.ref = process.env.GITHUB_REF; + this.workflow = process.env.GITHUB_WORKFLOW; + this.action = process.env.GITHUB_ACTION; + this.actor = process.env.GITHUB_ACTOR; + this.job = process.env.GITHUB_JOB; + this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); + this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); + this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; + this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; + this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; } - static getCall(id_token_url) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const httpclient = OidcClient.createHttpClient(); - const res = yield httpclient - .getJson(id_token_url) - .catch(error => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n - Error Message: ${error.result.message}`); - }); - const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; - if (!id_token) { - throw new Error('Response json body do not have ID Token field'); - } - return id_token; - }); + get issue() { + const payload = this.payload; + return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); } - static getIDToken(audience) { - return __awaiter(this, void 0, void 0, function* () { - try { - // New ID Token is requested from action service - let id_token_url = OidcClient.getIDTokenUrl(); - if (audience) { - const encodedAudience = encodeURIComponent(audience); - id_token_url = `${id_token_url}&audience=${encodedAudience}`; - } - core_1.debug(`ID token url is ${id_token_url}`); - const id_token = yield OidcClient.getCall(id_token_url); - core_1.setSecret(id_token); - return id_token; - } - catch (error) { - throw new Error(`Error message: ${error.message}`); - } - }); + get repo() { + if (process.env.GITHUB_REPOSITORY) { + const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); + return { owner, repo }; + } + if (this.payload.repository) { + return { + owner: this.payload.repository.owner.login, + repo: this.payload.repository.name + }; + } + throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); } } -exports.OidcClient = OidcClient; -//# sourceMappingURL=oidc-utils.js.map +exports.Context = Context; +//# sourceMappingURL=context.js.map /***/ }), -/***/ 2981: +/***/ 7914: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -1524,822 +1446,359 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; -const path = __importStar(__nccwpck_require__(1017)); -/** - * toPosixPath converts the given path to the posix form. On Windows, \\ will be - * replaced with /. - * - * @param pth. Path to transform. - * @return string Posix path. - */ -function toPosixPath(pth) { - return pth.replace(/[\\]/g, '/'); +exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; +const httpClient = __importStar(__nccwpck_require__(6255)); +function getAuthString(token, options) { + if (!token && !options.auth) { + throw new Error('Parameter token or opts.auth is required'); + } + else if (token && options.auth) { + throw new Error('Parameters token and opts.auth may not both be specified'); + } + return typeof options.auth === 'string' ? options.auth : `token ${token}`; } -exports.toPosixPath = toPosixPath; -/** - * toWin32Path converts the given path to the win32 form. On Linux, / will be - * replaced with \\. - * - * @param pth. Path to transform. - * @return string Win32 path. - */ -function toWin32Path(pth) { - return pth.replace(/[/]/g, '\\'); +exports.getAuthString = getAuthString; +function getProxyAgent(destinationUrl) { + const hc = new httpClient.HttpClient(); + return hc.getAgent(destinationUrl); } -exports.toWin32Path = toWin32Path; -/** - * toPlatformPath converts the given path to a platform-specific path. It does - * this by replacing instances of / and \ with the platform-specific path - * separator. - * - * @param pth The path to platformize. - * @return string The platform-specific path. - */ -function toPlatformPath(pth) { - return pth.replace(/[/\\]/g, path.sep); +exports.getProxyAgent = getProxyAgent; +function getApiBaseUrl() { + return process.env['GITHUB_API_URL'] || 'https://api.github.com'; } -exports.toPlatformPath = toPlatformPath; -//# sourceMappingURL=path-utils.js.map +exports.getApiBaseUrl = getApiBaseUrl; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 1327: +/***/ 3030: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; -const os_1 = __nccwpck_require__(2037); -const fs_1 = __nccwpck_require__(7147); -const { access, appendFile, writeFile } = fs_1.promises; -exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; -exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; -class Summary { - constructor() { - this._buffer = ''; - } - /** - * Finds the summary file path from the environment, rejects if env var is not found or file does not exist - * Also checks r/w permissions. - * - * @returns step summary file path - */ - filePath() { - return __awaiter(this, void 0, void 0, function* () { - if (this._filePath) { - return this._filePath; - } - const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; - if (!pathFromEnv) { - throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); - } - try { - yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); - } - catch (_a) { - throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); - } - this._filePath = pathFromEnv; - return this._filePath; - }); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const Utils = __importStar(__nccwpck_require__(7914)); +// octokit + plugins +const core_1 = __nccwpck_require__(8525); +const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); +const plugin_paginate_rest_1 = __nccwpck_require__(8945); +exports.context = new Context.Context(); +const baseUrl = Utils.getApiBaseUrl(); +exports.defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) } - /** - * Wraps content in an HTML tag, adding any HTML attributes - * - * @param {string} tag HTML tag to wrap - * @param {string | null} content content within the tag - * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add - * - * @returns {string} content wrapped in HTML element - */ - wrap(tag, content, attrs = {}) { - const htmlAttrs = Object.entries(attrs) - .map(([key, value]) => ` ${key}="${value}"`) - .join(''); - if (!content) { - return `<${tag}${htmlAttrs}>`; - } - return `<${tag}${htmlAttrs}>${content}`; +}; +exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); +/** + * Convience function to correctly format Octokit Options to pass into the constructor. + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +function getOctokitOptions(token, options) { + const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller + // Auth + const auth = Utils.getAuthString(token, opts); + if (auth) { + opts.auth = auth; } - /** - * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. - * - * @param {SummaryWriteOptions} [options] (optional) options for write operation - * - * @returns {Promise} summary instance - */ - write(options) { - return __awaiter(this, void 0, void 0, function* () { - const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); - const filePath = yield this.filePath(); - const writeFunc = overwrite ? writeFile : appendFile; - yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); - return this.emptyBuffer(); - }); + return opts; +} +exports.getOctokitOptions = getOctokitOptions; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 673: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; +const REGEX_IS_INSTALLATION = /^ghs_/; +const REGEX_IS_USER_TO_SERVER = /^ghu_/; +async function auth(token) { + const isApp = token.split(/\./).length === 3; + const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); + const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); + const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; + return { + type: "token", + token: token, + tokenType + }; +} + +/** + * Prefix token for usage in the Authorization header + * + * @param token OAuth token or JSON Web Token + */ +function withAuthorizationPrefix(token) { + if (token.split(/\./).length === 3) { + return `bearer ${token}`; + } + + return `token ${token}`; +} + +async function hook(token, request, route, parameters) { + const endpoint = request.endpoint.merge(route, parameters); + endpoint.headers.authorization = withAuthorizationPrefix(token); + return request(endpoint); +} + +const createTokenAuth = function createTokenAuth(token) { + if (!token) { + throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); + } + + if (typeof token !== "string") { + throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); + } + + token = token.replace(/^(token|bearer) +/i, ""); + return Object.assign(auth.bind(null, token), { + hook: hook.bind(null, token) + }); +}; + +exports.createTokenAuth = createTokenAuth; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 8525: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var universalUserAgent = __nccwpck_require__(5030); +var beforeAfterHook = __nccwpck_require__(3682); +var request = __nccwpck_require__(9353); +var graphql = __nccwpck_require__(6422); +var authToken = __nccwpck_require__(673); + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; } - /** - * Clears the summary buffer and wipes the summary file - * - * @returns {Summary} summary instance - */ - clear() { - return __awaiter(this, void 0, void 0, function* () { - return this.emptyBuffer().write({ overwrite: true }); - }); + } + + return target; +} + +const VERSION = "3.6.0"; + +const _excluded = ["authStrategy"]; +class Octokit { + constructor(options = {}) { + const hook = new beforeAfterHook.Collection(); + const requestDefaults = { + baseUrl: request.request.endpoint.DEFAULTS.baseUrl, + headers: {}, + request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type + hook: hook.bind(null, "request") + }), + mediaType: { + previews: [], + format: "" + } + }; // prepend default user agent with `options.userAgent` if set + + requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); + + if (options.baseUrl) { + requestDefaults.baseUrl = options.baseUrl; } - /** - * Returns the current summary buffer as a string - * - * @returns {string} string of summary buffer - */ - stringify() { - return this._buffer; - } - /** - * If the summary buffer is empty - * - * @returns {boolen} true if the buffer is empty - */ - isEmptyBuffer() { - return this._buffer.length === 0; - } - /** - * Resets the summary buffer without writing to summary file - * - * @returns {Summary} summary instance - */ - emptyBuffer() { - this._buffer = ''; - return this; - } - /** - * Adds raw text to the summary buffer - * - * @param {string} text content to add - * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) - * - * @returns {Summary} summary instance - */ - addRaw(text, addEOL = false) { - this._buffer += text; - return addEOL ? this.addEOL() : this; - } - /** - * Adds the operating system-specific end-of-line marker to the buffer - * - * @returns {Summary} summary instance - */ - addEOL() { - return this.addRaw(os_1.EOL); - } - /** - * Adds an HTML codeblock to the summary buffer - * - * @param {string} code content to render within fenced code block - * @param {string} lang (optional) language to syntax highlight code - * - * @returns {Summary} summary instance - */ - addCodeBlock(code, lang) { - const attrs = Object.assign({}, (lang && { lang })); - const element = this.wrap('pre', this.wrap('code', code), attrs); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML list to the summary buffer - * - * @param {string[]} items list of items to render - * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) - * - * @returns {Summary} summary instance - */ - addList(items, ordered = false) { - const tag = ordered ? 'ol' : 'ul'; - const listItems = items.map(item => this.wrap('li', item)).join(''); - const element = this.wrap(tag, listItems); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML table to the summary buffer - * - * @param {SummaryTableCell[]} rows table rows - * - * @returns {Summary} summary instance - */ - addTable(rows) { - const tableBody = rows - .map(row => { - const cells = row - .map(cell => { - if (typeof cell === 'string') { - return this.wrap('td', cell); - } - const { header, data, colspan, rowspan } = cell; - const tag = header ? 'th' : 'td'; - const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); - return this.wrap(tag, data, attrs); - }) - .join(''); - return this.wrap('tr', cells); - }) - .join(''); - const element = this.wrap('table', tableBody); - return this.addRaw(element).addEOL(); - } - /** - * Adds a collapsable HTML details element to the summary buffer - * - * @param {string} label text for the closed state - * @param {string} content collapsable content - * - * @returns {Summary} summary instance - */ - addDetails(label, content) { - const element = this.wrap('details', this.wrap('summary', label) + content); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML image tag to the summary buffer - * - * @param {string} src path to the image you to embed - * @param {string} alt text description of the image - * @param {SummaryImageOptions} options (optional) addition image attributes - * - * @returns {Summary} summary instance - */ - addImage(src, alt, options) { - const { width, height } = options || {}; - const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); - const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML section heading element - * - * @param {string} text heading text - * @param {number | string} [level=1] (optional) the heading level, default: 1 - * - * @returns {Summary} summary instance - */ - addHeading(text, level) { - const tag = `h${level}`; - const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) - ? tag - : 'h1'; - const element = this.wrap(allowedTag, text); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML thematic break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addSeparator() { - const element = this.wrap('hr', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML line break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addBreak() { - const element = this.wrap('br', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML blockquote to the summary buffer - * - * @param {string} text quote text - * @param {string} cite (optional) citation url - * - * @returns {Summary} summary instance - */ - addQuote(text, cite) { - const attrs = Object.assign({}, (cite && { cite })); - const element = this.wrap('blockquote', text, attrs); - return this.addRaw(element).addEOL(); + + if (options.previews) { + requestDefaults.mediaType.previews = options.previews; } - /** - * Adds an HTML anchor tag to the summary buffer - * - * @param {string} text link text/content - * @param {string} href hyperlink - * - * @returns {Summary} summary instance - */ - addLink(text, href) { - const element = this.wrap('a', text, { href }); - return this.addRaw(element).addEOL(); + + if (options.timeZone) { + requestDefaults.headers["time-zone"] = options.timeZone; } -} -const _summary = new Summary(); -/** - * @deprecated use `core.summary` - */ -exports.markdownSummary = _summary; -exports.summary = _summary; -//# sourceMappingURL=summary.js.map -/***/ }), + this.request = request.request.defaults(requestDefaults); + this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); + this.log = Object.assign({ + debug: () => {}, + info: () => {}, + warn: console.warn.bind(console), + error: console.error.bind(console) + }, options.log); + this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance + // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. + // (2) If only `options.auth` is set, use the default token authentication strategy. + // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. + // TODO: type `options.auth` based on `options.authStrategy`. -/***/ 5278: -/***/ ((__unused_webpack_module, exports) => { + if (!options.authStrategy) { + if (!options.auth) { + // (1) + this.auth = async () => ({ + type: "unauthenticated" + }); + } else { + // (2) + const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ -"use strict"; + hook.wrap("request", auth.hook); + this.auth = auth; + } + } else { + const { + authStrategy + } = options, + otherOptions = _objectWithoutProperties(options, _excluded); -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toCommandProperties = exports.toCommandValue = void 0; -/** - * Sanitizes an input into a string so it can be passed into issueCommand safely - * @param input input to sanitize into a string - */ -function toCommandValue(input) { - if (input === null || input === undefined) { - return ''; - } - else if (typeof input === 'string' || input instanceof String) { - return input; - } - return JSON.stringify(input); -} -exports.toCommandValue = toCommandValue; -/** - * - * @param annotationProperties - * @returns The command properties to send with the actual annotation command - * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 - */ -function toCommandProperties(annotationProperties) { - if (!Object.keys(annotationProperties).length) { - return {}; - } - return { - title: annotationProperties.title, - file: annotationProperties.file, - line: annotationProperties.startLine, - endLine: annotationProperties.endLine, - col: annotationProperties.startColumn, - endColumn: annotationProperties.endColumn - }; -} -exports.toCommandProperties = toCommandProperties; -//# sourceMappingURL=utils.js.map + const auth = authStrategy(Object.assign({ + request: this.request, + log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. + octokit: this, + octokitOptions: otherOptions + }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ -/***/ }), + hook.wrap("request", auth.hook); + this.auth = auth; + } // apply plugins + // https://stackoverflow.com/a/16345172 -/***/ 4087: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; + const classConstructor = this.constructor; + classConstructor.plugins.forEach(plugin => { + Object.assign(this, plugin(this, options)); + }); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Context = void 0; -const fs_1 = __nccwpck_require__(7147); -const os_1 = __nccwpck_require__(2037); -class Context { - /** - * Hydrate the context from the environment - */ - constructor() { - var _a, _b, _c; - this.payload = {}; - if (process.env.GITHUB_EVENT_PATH) { - if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { - this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); - } - else { - const path = process.env.GITHUB_EVENT_PATH; - process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); - } - } - this.eventName = process.env.GITHUB_EVENT_NAME; - this.sha = process.env.GITHUB_SHA; - this.ref = process.env.GITHUB_REF; - this.workflow = process.env.GITHUB_WORKFLOW; - this.action = process.env.GITHUB_ACTION; - this.actor = process.env.GITHUB_ACTOR; - this.job = process.env.GITHUB_JOB; - this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); - this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); - this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; - this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; - this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; - } - get issue() { - const payload = this.payload; - return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); - } - get repo() { - if (process.env.GITHUB_REPOSITORY) { - const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); - return { owner, repo }; - } - if (this.payload.repository) { - return { - owner: this.payload.repository.owner.login, - repo: this.payload.repository.name - }; + static defaults(defaults) { + const OctokitWithDefaults = class extends this { + constructor(...args) { + const options = args[0] || {}; + + if (typeof defaults === "function") { + super(defaults(options)); + return; } - throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); - } -} -exports.Context = Context; -//# sourceMappingURL=context.js.map -/***/ }), + super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { + userAgent: `${options.userAgent} ${defaults.userAgent}` + } : null)); + } -/***/ 7914: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + }; + return OctokitWithDefaults; + } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; -const httpClient = __importStar(__nccwpck_require__(6255)); -function getAuthString(token, options) { - if (!token && !options.auth) { - throw new Error('Parameter token or opts.auth is required'); - } - else if (token && options.auth) { - throw new Error('Parameters token and opts.auth may not both be specified'); - } - return typeof options.auth === 'string' ? options.auth : `token ${token}`; -} -exports.getAuthString = getAuthString; -function getProxyAgent(destinationUrl) { - const hc = new httpClient.HttpClient(); - return hc.getAgent(destinationUrl); -} -exports.getProxyAgent = getProxyAgent; -function getApiBaseUrl() { - return process.env['GITHUB_API_URL'] || 'https://api.github.com'; -} -exports.getApiBaseUrl = getApiBaseUrl; -//# sourceMappingURL=utils.js.map + static plugin(...newPlugins) { + var _a; -/***/ }), + const currentPlugins = this.plugins; + const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); + return NewOctokit; + } -/***/ 3030: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +} +Octokit.VERSION = VERSION; +Octokit.plugins = []; -"use strict"; +exports.Octokit = Octokit; +//# sourceMappingURL=index.js.map -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(4087)); -const Utils = __importStar(__nccwpck_require__(7914)); -// octokit + plugins -const core_1 = __nccwpck_require__(8525); -const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); -const plugin_paginate_rest_1 = __nccwpck_require__(8945); -exports.context = new Context.Context(); -const baseUrl = Utils.getApiBaseUrl(); -exports.defaults = { - baseUrl, - request: { - agent: Utils.getProxyAgent(baseUrl) - } -}; -exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); -/** - * Convience function to correctly format Octokit Options to pass into the constructor. - * - * @param token the repo PAT or GITHUB_TOKEN - * @param options other options to set - */ -function getOctokitOptions(token, options) { - const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller - // Auth - const auth = Utils.getAuthString(token, opts); - if (auth) { - opts.auth = auth; - } - return opts; -} -exports.getOctokitOptions = getOctokitOptions; -//# sourceMappingURL=utils.js.map /***/ }), -/***/ 673: -/***/ ((__unused_webpack_module, exports) => { +/***/ 8713: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; -const REGEX_IS_INSTALLATION = /^ghs_/; -const REGEX_IS_USER_TO_SERVER = /^ghu_/; -async function auth(token) { - const isApp = token.split(/\./).length === 3; - const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); - const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); - const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; - return { - type: "token", - token: token, - tokenType - }; -} +var isPlainObject = __nccwpck_require__(3287); +var universalUserAgent = __nccwpck_require__(5030); -/** - * Prefix token for usage in the Authorization header - * - * @param token OAuth token or JSON Web Token - */ -function withAuthorizationPrefix(token) { - if (token.split(/\./).length === 3) { - return `bearer ${token}`; +function lowercaseKeys(object) { + if (!object) { + return {}; } - return `token ${token}`; -} - -async function hook(token, request, route, parameters) { - const endpoint = request.endpoint.merge(route, parameters); - endpoint.headers.authorization = withAuthorizationPrefix(token); - return request(endpoint); -} - -const createTokenAuth = function createTokenAuth(token) { - if (!token) { - throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); - } - - if (typeof token !== "string") { - throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); - } - - token = token.replace(/^(token|bearer) +/i, ""); - return Object.assign(auth.bind(null, token), { - hook: hook.bind(null, token) - }); -}; - -exports.createTokenAuth = createTokenAuth; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 8525: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -var universalUserAgent = __nccwpck_require__(5030); -var beforeAfterHook = __nccwpck_require__(3682); -var request = __nccwpck_require__(9353); -var graphql = __nccwpck_require__(6422); -var authToken = __nccwpck_require__(673); - -function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; - - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } - - return target; -} - -function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - - var target = _objectWithoutPropertiesLoose(source, excluded); - - var key, i; - - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } - - return target; -} - -const VERSION = "3.6.0"; - -const _excluded = ["authStrategy"]; -class Octokit { - constructor(options = {}) { - const hook = new beforeAfterHook.Collection(); - const requestDefaults = { - baseUrl: request.request.endpoint.DEFAULTS.baseUrl, - headers: {}, - request: Object.assign({}, options.request, { - // @ts-ignore internal usage only, no need to type - hook: hook.bind(null, "request") - }), - mediaType: { - previews: [], - format: "" - } - }; // prepend default user agent with `options.userAgent` if set - - requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); - - if (options.baseUrl) { - requestDefaults.baseUrl = options.baseUrl; - } - - if (options.previews) { - requestDefaults.mediaType.previews = options.previews; - } - - if (options.timeZone) { - requestDefaults.headers["time-zone"] = options.timeZone; - } - - this.request = request.request.defaults(requestDefaults); - this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); - this.log = Object.assign({ - debug: () => {}, - info: () => {}, - warn: console.warn.bind(console), - error: console.error.bind(console) - }, options.log); - this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance - // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. - // (2) If only `options.auth` is set, use the default token authentication strategy. - // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. - // TODO: type `options.auth` based on `options.authStrategy`. - - if (!options.authStrategy) { - if (!options.auth) { - // (1) - this.auth = async () => ({ - type: "unauthenticated" - }); - } else { - // (2) - const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } - } else { - const { - authStrategy - } = options, - otherOptions = _objectWithoutProperties(options, _excluded); - - const auth = authStrategy(Object.assign({ - request: this.request, - log: this.log, - // we pass the current octokit instance as well as its constructor options - // to allow for authentication strategies that return a new octokit instance - // that shares the same internal state as the current one. The original - // requirement for this was the "event-octokit" authentication strategy - // of https://github.com/probot/octokit-auth-probot. - octokit: this, - octokitOptions: otherOptions - }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } // apply plugins - // https://stackoverflow.com/a/16345172 - - - const classConstructor = this.constructor; - classConstructor.plugins.forEach(plugin => { - Object.assign(this, plugin(this, options)); - }); - } - - static defaults(defaults) { - const OctokitWithDefaults = class extends this { - constructor(...args) { - const options = args[0] || {}; - - if (typeof defaults === "function") { - super(defaults(options)); - return; - } - - super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { - userAgent: `${options.userAgent} ${defaults.userAgent}` - } : null)); - } - - }; - return OctokitWithDefaults; - } - /** - * Attach a plugin (or many) to your Octokit instance. - * - * @example - * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) - */ - - - static plugin(...newPlugins) { - var _a; - - const currentPlugins = this.plugins; - const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); - return NewOctokit; - } - -} -Octokit.VERSION = VERSION; -Octokit.plugins = []; - -exports.Octokit = Octokit; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 8713: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -var isPlainObject = __nccwpck_require__(3287); -var universalUserAgent = __nccwpck_require__(5030); - -function lowercaseKeys(object) { - if (!object) { - return {}; - } - - return Object.keys(object).reduce((newObj, key) => { - newObj[key.toLowerCase()] = object[key]; - return newObj; - }, {}); + return Object.keys(object).reduce((newObj, key) => { + newObj[key.toLowerCase()] = object[key]; + return newObj; + }, {}); } function mergeDeep(defaults, options) { @@ -10172,4152 +9631,2542 @@ exports.isPlainObject = isPlainObject; /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 467: +/***/ ((module, exports, __nccwpck_require__) => { -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +"use strict"; -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +Object.defineProperty(exports, "__esModule", ({ value: true })); -module.exports = Hash; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } +var Stream = _interopDefault(__nccwpck_require__(2781)); +var http = _interopDefault(__nccwpck_require__(3685)); +var Url = _interopDefault(__nccwpck_require__(7310)); +var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); +var https = _interopDefault(__nccwpck_require__(5687)); +var zlib = _interopDefault(__nccwpck_require__(9796)); -/***/ }), +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); +class Blob { + constructor() { + this[TYPE] = ''; -/***/ }), + const blobParts = arguments[0]; + const options = arguments[1]; -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const buffers = []; + let size = 0; -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + this[BUFFER] = Buffer.concat(buffers); -module.exports = Map; + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); -/***/ }), + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); /** - * Creates a map cache object to store key-value pairs. + * fetch-error.js * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * FetchError interface for operational errors */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; - - -/***/ }), - -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Built-in value references. */ -var Symbol = root.Symbol; - -module.exports = Symbol; - - -/***/ }), - -/***/ 4356: -/***/ ((module) => { /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. + * Create FetchError instance * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; - while (++index < length) { - result[index] = iteratee(array[index], index, array); + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; } - return result; -} -module.exports = arrayMap; + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; -/***/ }), +let convert; +try { + convert = (__nccwpck_require__(2877).convert); +} catch (e) {} -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS = Symbol('Body internals'); -var eq = __nccwpck_require__(1901); +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; /** - * Gets the index at which the `key` is found in `array` of key-value pairs. + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -module.exports = assocIndexOf; - - -/***/ }), - -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function Body(body) { + var _this = this; -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; - var index = 0, - length = path.length; + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } } -module.exports = baseGet; +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + get bodyUsed() { + return this[INTERNALS].disturbed; + }, -/***/ }), + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, -module.exports = baseGetTag; + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; -/***/ }), + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; +function consumeBody() { + var _this4 = this; -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + this[INTERNALS].disturbed = true; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + let body = this.body; -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -module.exports = baseIsNative; + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } -/***/ }), + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + return new Body.Promise(function (resolve, reject) { + let resTimeout; -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } -module.exports = baseToString; + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + accumBytes += chunk.length; + accum.push(chunk); + }); -/***/ }), + body.on('end', function () { + if (abort) { + return; + } -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + clearTimeout(resTimeout); -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} /** - * Casts `value` to a path array if it's not one. + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } -module.exports = coreJsData; + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } -/***/ }), + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); -/***/ 2085: -/***/ ((module) => { + // html5 + if (!res && str) { + res = / { + // prevent decode issues when sites use incorrect encoding + // ref: https://hsivonen.fi/encoding-menu/ + if (charset === 'gb2312' || charset === 'gbk') { + charset = 'gb18030'; + } + } -var isKeyable = __nccwpck_require__(3308); + // turn raw buffers into a single utf-8 buffer + return convert(buffer, 'UTF-8', charset).toString(); +} /** - * Gets the data for `map`. + * Detect a URLSearchParams object + * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. + * @param Object obj Object to detect by type or brand + * @return String */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - - -/***/ }), - -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function isURLSearchParams(obj) { + // Duck-typing as a necessary condition. + if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { + return false; + } -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + // Brand-checking and more duck-typing as optional condition. + return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; +} /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. + * Check if `obj` is a W3C `Blob` object (which `File` inherits from) + * @param {*} obj + * @return {boolean} */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -module.exports = getNative; - - -/***/ }), - -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; +function isBlob(obj) { + return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); } -module.exports = getRawTag; - - -/***/ }), - -/***/ 3542: -/***/ ((module) => { - /** - * Gets the value at `key` of `object`. + * Clone body given Res/Req instance * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. + * @param Mixed instance Response or Request instance + * @return Mixed */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -module.exports = getValue; - - -/***/ }), +function clone(instance) { + let p1, p2; + let body = instance.body; -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } -var nativeCreate = __nccwpck_require__(3041); + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof Stream && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; + return body; } -module.exports = hashClear; - - -/***/ }), - -/***/ 712: -/***/ ((module) => { - /** - * Removes `key` and its value from the hash. + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} - -module.exports = hashDelete; - - -/***/ }), - -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Gets the hash value for `key`. + * This function assumes that instance.body is present. * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @param Mixed instance Any options.body input */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof Stream) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } } -module.exports = hashGet; - - -/***/ }), - -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - /** - * Checks if a hash value for `key` exists. + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), - -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getTotalBytes(instance) { + const body = instance.body; -var nativeCreate = __nccwpck_require__(3041); -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} /** - * Sets the hash `key` to `value`. + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. + * @param Body instance Instance of Body + * @return Void */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -module.exports = hashSet; - - -/***/ }), +function writeToStream(dest, instance) { + const body = instance.body; -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } +} -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; +// expose Promise +Body.Promise = global.Promise; /** - * Checks if `value` is a property name and not a property path. + * headers.js * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + * Headers class offers convenient helpers */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} - -module.exports = isKey; +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; -/***/ }), +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } +} -/***/ 3308: -/***/ ((module) => { +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } +} /** - * Checks if `value` is suitable for use as unique object key. + * Find the key in the map object given a header name. + * + * Returns undefined if not found. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + * @param String name Header name + * @return String|Undefined */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; } -module.exports = isKeyable; - +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; -/***/ }), + this[MAP] = Object.create(null); -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); -var coreJsData = __nccwpck_require__(8380); + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + return; + } -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } -module.exports = isMasked; + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } -/***/ }), + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } -/***/ 9792: -/***/ ((module) => { + return this[MAP][key].join(', '); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; -module.exports = listCacheClear; + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } -/***/ }), + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } -var assocIndexOf = __nccwpck_require__(6752); + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } -/** Built-in value references. */ -var splice = arrayProto.splice; + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } } +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -module.exports = listCacheDelete; - +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); -/***/ }), +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; -var assocIndexOf = __nccwpck_require__(6752); + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); +const INTERNAL = Symbol('internal'); - return index < 0 ? undefined : data[index][1]; +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; } -module.exports = listCacheGet; +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; -/***/ }), + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNAL].index = index + 1; -var assocIndexOf = __nccwpck_require__(6752); + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), - -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); /** - * Sets the list cache `key` to `value`. + * Export the Headers object in a form that Node.js can consume. * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. + * @param Headers headers + * @return Object */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -module.exports = listCacheSet; - - -/***/ }), +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + return obj; +} /** - * Removes all key-value entries from the map. + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. * - * @private - * @name clear - * @memberOf MapCache + * @param Object obj Object of headers + * @return Headers */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; } -module.exports = mapCacheClear; - - -/***/ }), - -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$1 = Symbol('Response internals'); -var getMapData = __nccwpck_require__(9980); +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; /** - * Removes `key` and its value from the map. + * Response class * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} - -module.exports = mapCacheDelete; +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Body.call(this, body, opts); -/***/ }), + const status = opts.status || 200; + const headers = new Headers(opts.headers); -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -var getMapData = __nccwpck_require__(9980); + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + get url() { + return this[INTERNALS$1].url || ''; + } -module.exports = mapCacheGet; + get status() { + return this[INTERNALS$1].status; + } + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } -/***/ }), + get redirected() { + return this[INTERNALS$1].counter > 0; + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + get statusText() { + return this[INTERNALS$1].statusText; + } -var getMapData = __nccwpck_require__(9980); + get headers() { + return this[INTERNALS$1].headers; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } } -module.exports = mapCacheHas; +Body.mixIn(Response.prototype); +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); -/***/ }), +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; -var getMapData = __nccwpck_require__(9980); +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; /** - * Sets the map `key` to `value`. + * Wrapper around `new URL` to handle arbitrary URLs * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); } -module.exports = mapCacheSet; - - -/***/ }), - -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var memoize = __nccwpck_require__(9885); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * Check if a value is an instance of Request. * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. + * @param Mixed input + * @return Boolean */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} - var cache = result.cache; - return result; +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); } -module.exports = memoizeCapped; +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let parsedURL; -/***/ }), + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); -var getNative = __nccwpck_require__(4479); + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; -module.exports = nativeCreate; + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + const headers = new Headers(init.headers || input.headers || {}); -/***/ }), + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -/***/ 4200: -/***/ ((module) => { + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} - -module.exports = objectToString; - - -/***/ }), - -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; -var freeGlobal = __nccwpck_require__(2085); + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + get method() { + return this[INTERNALS$2].method; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } -module.exports = root; + get headers() { + return this[INTERNALS$2].headers; + } + get redirect() { + return this[INTERNALS$2].redirect; + } -/***/ }), + get signal() { + return this[INTERNALS$2].signal; + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} -var memoizeCapped = __nccwpck_require__(9422); +Body.mixIn(Request.prototype); -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); /** - * Converts `string` to a property path array. + * Convert a Request to Node.js http request options. * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. + * @param Request A Request instance + * @return Object The options object to be passed to http.request */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); -/***/ }), + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } -var isSymbol = __nccwpck_require__(6403); + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } -module.exports = toKey; + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } -/***/ }), + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } -/***/ 6928: -/***/ ((module) => { + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} /** - * Converts `func` to its source code. + * abort-error.js * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. + * AbortError interface for cancelled requests */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -module.exports = toSource; - - -/***/ }), - -/***/ 1901: -/***/ ((module) => { /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false + * Create AbortError instance * - * _.eq(NaN, NaN); - * // => true + * @param String message Error message for human + * @return AbortError */ -function eq(value, other) { - return value === other || (value !== value && other !== other); +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); } -module.exports = eq; +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; +const URL$1 = Url.URL || whatwgUrl.URL; -/***/ }), +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; -var baseGet = __nccwpck_require__(5758); + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 + * Fetch function * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} +function fetch(url, opts) { -module.exports = get; + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + Body.Promise = fetch.Promise; -/***/ }), + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); -/***/ 4869: -/***/ ((module) => { + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + let response = null; -module.exports = isArray; + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + request.body.destroy(error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + if (signal && signal.aborted) { + abort(); + return; + } -/***/ }), + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // send request + const req = send(options); + let reqTimeout; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -module.exports = isFunction; + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + finalize(); + }); -/***/ }), + req.on('response', function (res) { + clearTimeout(reqTimeout); -/***/ 3334: -/***/ ((module) => { + const headers = createHeadersLenient(res.headers); -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); -module.exports = isObject; + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } -/***/ }), + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } -/***/ 5926: -/***/ ((module) => { + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} + if (!isDomainOrSubdomain(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } -module.exports = isObjectLike; + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } -/***/ }), + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} + // HTTP-network fetch step 12.1.1.4: handle content codings -module.exports = isSymbol; + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; -/***/ }), + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + return; + } -var MapCache = __nccwpck_require__(938); + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + writeToStream(req, request); + }); +} /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] + * Redirect code matching * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * @param Number code Status code + * @return Boolean */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; -// Expose `MapCache`. -memoize.Cache = MapCache; +// expose Promise +fetch.Promise = global.Promise; -module.exports = memoize; +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports["default"] = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; /***/ }), -/***/ 2931: +/***/ 2299: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var baseToString = __nccwpck_require__(6792); +"use strict"; -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); -} -module.exports = toString; +var punycode = __nccwpck_require__(5477); +var mappingTable = __nccwpck_require__(1907); +var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 +}; -/***/ }), +function normalize(str) { // fix bug in v8 + return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); +} -/***/ 467: -/***/ ((module, exports, __nccwpck_require__) => { +function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; -"use strict"; + while (start <= end) { + var mid = Math.floor((start + end) / 2); + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + return null; +} -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } +var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; -var Stream = _interopDefault(__nccwpck_require__(2781)); -var http = _interopDefault(__nccwpck_require__(3685)); -var Url = _interopDefault(__nccwpck_require__(7310)); -var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); -var https = _interopDefault(__nccwpck_require__(5687)); -var zlib = _interopDefault(__nccwpck_require__(9796)); +function countSymbols(string) { + return string + // replace every surrogate pair with a BMP symbol + .replace(regexAstralSymbols, '_') + // then get the length + .length; +} -// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js +function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; -// fix for "Readable" isn't a named export issue -const Readable = Stream.Readable; + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); -const BUFFER = Symbol('buffer'); -const TYPE = Symbol('type'); + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } -class Blob { - constructor() { - this[TYPE] = ''; + processed += String.fromCodePoint(codePoint); + break; + } + } - const blobParts = arguments[0]; - const options = arguments[1]; + return { + string: processed, + error: hasError + }; +} - const buffers = []; - let size = 0; +var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; - if (blobParts) { - const a = blobParts; - const length = Number(a.length); - for (let i = 0; i < length; i++) { - const element = a[i]; - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = element[BUFFER]; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); - } - size += buffer.length; - buffers.push(buffer); - } - } +function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } - this[BUFFER] = Buffer.concat(buffers); + var error = false; - let type = options && options.type !== undefined && String(options.type).toLowerCase(); - if (type && !/[^\u0020-\u007E]/.test(type)) { - this[TYPE] = type; - } - } - get size() { - return this[BUFFER].length; - } - get type() { - return this[TYPE]; - } - text() { - return Promise.resolve(this[BUFFER].toString()); - } - arrayBuffer() { - const buf = this[BUFFER]; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); - } - stream() { - const readable = new Readable(); - readable._read = function () {}; - readable.push(this[BUFFER]); - readable.push(null); - return readable; - } - toString() { - return '[object Blob]'; - } - slice() { - const size = this.size; + if (normalize(label) !== label || + (label[3] === "-" && label[4] === "-") || + label[0] === "-" || label[label.length - 1] === "-" || + label.indexOf(".") !== -1 || + label.search(combiningMarksRegex) === 0) { + error = true; + } - const start = arguments[0]; - const end = arguments[1]; - let relativeStart, relativeEnd; - if (start === undefined) { - relativeStart = 0; - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); - } else { - relativeStart = Math.min(start, size); - } - if (end === undefined) { - relativeEnd = size; - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); - } else { - relativeEnd = Math.min(end, size); - } - const span = Math.max(relativeEnd - relativeStart, 0); + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || + (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && + status[1] !== "valid" && status[1] !== "deviation")) { + error = true; + break; + } + } - const buffer = this[BUFFER]; - const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); - const blob = new Blob([], { type: arguments[2] }); - blob[BUFFER] = slicedBuffer; - return blob; - } + return { + label: label, + error: error + }; } -Object.defineProperties(Blob.prototype, { - size: { enumerable: true }, - type: { enumerable: true }, - slice: { enumerable: true } -}); - -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); - -/** - * fetch-error.js - * - * FetchError interface for operational errors - */ - -/** - * Create FetchError instance - * - * @param String message Error message for human - * @param String type Error type for machine - * @param String systemError For Node.js system error - * @return FetchError - */ -function FetchError(message, type, systemError) { - Error.call(this, message); - - this.message = message; - this.type = type; +function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); - // when err.type is `system`, err.code contains system error code - if (systemError) { - this.code = this.errno = systemError.code; + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch(e) { + result.error = true; + } } - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); + return { + string: labels.join("."), + error: result.error + }; } -FetchError.prototype = Object.create(Error.prototype); -FetchError.prototype.constructor = FetchError; -FetchError.prototype.name = 'FetchError'; +module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch(e) { + result.error = true; + return l; + } + }); -let convert; -try { - convert = (__nccwpck_require__(2877).convert); -} catch (e) {} + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } -const INTERNALS = Symbol('Body internals'); + for (var i=0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } -// fix an issue where "PassThrough" isn't a named export for node <10 -const PassThrough = Stream.PassThrough; + if (result.error) return null; + return labels.join("."); +}; -/** - * Body mixin - * - * Ref: https://fetch.spec.whatwg.org/#body - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -function Body(body) { - var _this = this; +module.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref$size = _ref.size; + return { + domain: result.string, + error: result.error + }; +}; - let size = _ref$size === undefined ? 0 : _ref$size; - var _ref$timeout = _ref.timeout; - let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; +module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - if (body == null) { - // body is undefined or null - body = null; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - body = Buffer.from(body.toString()); - } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - body = Buffer.from(body); - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); - } else if (body instanceof Stream) ; else { - // none of the above - // coerce to string then buffer - body = Buffer.from(String(body)); - } - this[INTERNALS] = { - body, - disturbed: false, - error: null - }; - this.size = size; - this.timeout = timeout; - if (body instanceof Stream) { - body.on('error', function (err) { - const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); - _this[INTERNALS].error = error; - }); - } -} +/***/ }), -Body.prototype = { - get body() { - return this[INTERNALS].body; - }, +/***/ 5871: +/***/ ((module) => { - get bodyUsed() { - return this[INTERNALS].disturbed; - }, +"use strict"; - /** - * Decode response as ArrayBuffer - * - * @return Promise - */ - arrayBuffer() { - return consumeBody.call(this).then(function (buf) { - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - }); - }, - /** - * Return raw response as Blob - * - * @return Promise - */ - blob() { - let ct = this.headers && this.headers.get('content-type') || ''; - return consumeBody.call(this).then(function (buf) { - return Object.assign( - // Prevent copying - new Blob([], { - type: ct.toLowerCase() - }), { - [BUFFER]: buf - }); - }); - }, +var conversions = {}; +module.exports = conversions; - /** - * Decode response as json - * - * @return Promise - */ - json() { - var _this2 = this; +function sign(x) { + return x < 0 ? -1 : 1; +} - return consumeBody.call(this).then(function (buffer) { - try { - return JSON.parse(buffer.toString()); - } catch (err) { - return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); - } - }); - }, +function evenRound(x) { + // Round x to the nearest integer, choosing the even integer if it lies halfway between two. + if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) + return Math.floor(x); + } else { + return Math.round(x); + } +} - /** - * Decode response as text - * - * @return Promise - */ - text() { - return consumeBody.call(this).then(function (buffer) { - return buffer.toString(); - }); - }, +function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength; + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); + const upperBound = Math.pow(2, bitLength) - 1; - /** - * Decode response as buffer (non-spec api) - * - * @return Promise - */ - buffer() { - return consumeBody.call(this); - }, + const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); + const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - /** - * Decode response as text, while automatically detecting the encoding and - * trying to decode to UTF-8 (non-spec api) - * - * @return Promise - */ - textConverted() { - var _this3 = this; + return function(V, opts) { + if (!opts) opts = {}; - return consumeBody.call(this).then(function (buffer) { - return convertBody(buffer, _this3.headers); - }); - } -}; + let x = +V; -// In browsers, all properties are enumerable. -Object.defineProperties(Body.prototype, { - body: { enumerable: true }, - bodyUsed: { enumerable: true }, - arrayBuffer: { enumerable: true }, - blob: { enumerable: true }, - json: { enumerable: true }, - text: { enumerable: true } -}); + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite number"); + } -Body.mixIn = function (proto) { - for (const name of Object.getOwnPropertyNames(Body.prototype)) { - // istanbul ignore else: future proof - if (!(name in proto)) { - const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); - Object.defineProperty(proto, name, desc); - } - } -}; + x = sign(x) * Math.floor(Math.abs(x)); + if (x < lowerBound || x > upperBound) { + throw new TypeError("Argument is not in byte range"); + } -/** - * Consume and convert an entire Body to a Buffer. - * - * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body - * - * @return Promise - */ -function consumeBody() { - var _this4 = this; + return x; + } - if (this[INTERNALS].disturbed) { - return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); - } + if (!isNaN(x) && opts.clamp) { + x = evenRound(x); - this[INTERNALS].disturbed = true; + if (x < lowerBound) x = lowerBound; + if (x > upperBound) x = upperBound; + return x; + } - if (this[INTERNALS].error) { - return Body.Promise.reject(this[INTERNALS].error); - } + if (!Number.isFinite(x) || x === 0) { + return 0; + } - let body = this.body; + x = sign(x) * Math.floor(Math.abs(x)); + x = x % moduloVal; - // body is null - if (body === null) { - return Body.Promise.resolve(Buffer.alloc(0)); - } + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal; + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal; + } else if (x === -0) { // don't return negative zero + return 0; + } + } - // body is blob - if (isBlob(body)) { - body = body.stream(); - } + return x; + } +} - // body is buffer - if (Buffer.isBuffer(body)) { - return Body.Promise.resolve(body); - } +conversions["void"] = function () { + return undefined; +}; - // istanbul ignore if: should never happen - if (!(body instanceof Stream)) { - return Body.Promise.resolve(Buffer.alloc(0)); - } +conversions["boolean"] = function (val) { + return !!val; +}; - // body is stream - // get ready to actually consume the body - let accum = []; - let accumBytes = 0; - let abort = false; +conversions["byte"] = createNumberConversion(8, { unsigned: false }); +conversions["octet"] = createNumberConversion(8, { unsigned: true }); - return new Body.Promise(function (resolve, reject) { - let resTimeout; +conversions["short"] = createNumberConversion(16, { unsigned: false }); +conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - // allow timeout on slow response body - if (_this4.timeout) { - resTimeout = setTimeout(function () { - abort = true; - reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); - }, _this4.timeout); - } +conversions["long"] = createNumberConversion(32, { unsigned: false }); +conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - // handle stream errors - body.on('error', function (err) { - if (err.name === 'AbortError') { - // if the request was aborted, reject with this Error - abort = true; - reject(err); - } else { - // other errors, such as incorrect content-encoding - reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); - } - }); +conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); +conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - body.on('data', function (chunk) { - if (abort || chunk === null) { - return; - } +conversions["double"] = function (V) { + const x = +V; - if (_this4.size && accumBytes + chunk.length > _this4.size) { - abort = true; - reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); - return; - } + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite floating-point value"); + } - accumBytes += chunk.length; - accum.push(chunk); - }); + return x; +}; - body.on('end', function () { - if (abort) { - return; - } +conversions["unrestricted double"] = function (V) { + const x = +V; - clearTimeout(resTimeout); + if (isNaN(x)) { + throw new TypeError("Argument is NaN"); + } - try { - resolve(Buffer.concat(accum, accumBytes)); - } catch (err) { - // handle streams that have accumulated too much data (issue #414) - reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - }); -} + return x; +}; -/** - * Detect buffer encoding and convert to target encoding - * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding - * - * @param Buffer buffer Incoming buffer - * @param String encoding Target encoding - * @return String - */ -function convertBody(buffer, headers) { - if (typeof convert !== 'function') { - throw new Error('The package `encoding` must be installed to use the textConverted() function'); - } +// not quite valid, but good enough for JS +conversions["float"] = conversions["double"]; +conversions["unrestricted float"] = conversions["unrestricted double"]; - const ct = headers.get('content-type'); - let charset = 'utf-8'; - let res, str; +conversions["DOMString"] = function (V, opts) { + if (!opts) opts = {}; - // header - if (ct) { - res = /charset=([^;]*)/i.exec(ct); - } + if (opts.treatNullAsEmptyString && V === null) { + return ""; + } - // no charset in content type, peek at response body for at most 1024 bytes - str = buffer.slice(0, 1024).toString(); + return String(V); +}; - // html5 - if (!res && str) { - res = / 255) { + throw new TypeError("Argument is not a valid bytestring"); + } + } - // html4 - if (!res && str) { - res = / 0xDFFF) { + U.push(String.fromCodePoint(c)); + } else if (0xDC00 <= c && c <= 0xDFFF) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + const d = S.charCodeAt(i + 1); + if (0xDC00 <= d && d <= 0xDFFF) { + const a = c & 0x3FF; + const b = d & 0x3FF; + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); + ++i; + } else { + U.push(String.fromCodePoint(0xFFFD)); + } + } + } + } - // xml - if (!res && str) { - res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); - } + return U.join(''); +}; - // found charset - if (res) { - charset = res.pop(); +conversions["Date"] = function (V, opts) { + if (!(V instanceof Date)) { + throw new TypeError("Argument is not a Date object"); + } + if (isNaN(V)) { + return undefined; + } - // prevent decode issues when sites use incorrect encoding - // ref: https://hsivonen.fi/encoding-menu/ - if (charset === 'gb2312' || charset === 'gbk') { - charset = 'gb18030'; - } - } + return V; +}; - // turn raw buffers into a single utf-8 buffer - return convert(buffer, 'UTF-8', charset).toString(); -} +conversions["RegExp"] = function (V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V); + } -/** - * Detect a URLSearchParams object - * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 - * - * @param Object obj Object to detect by type or brand - * @return String - */ -function isURLSearchParams(obj) { - // Duck-typing as a necessary condition. - if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { - return false; - } + return V; +}; - // Brand-checking and more duck-typing as optional condition. - return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; -} -/** - * Check if `obj` is a W3C `Blob` object (which `File` inherits from) - * @param {*} obj - * @return {boolean} - */ -function isBlob(obj) { - return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); -} +/***/ }), -/** - * Clone body given Res/Req instance - * - * @param Mixed instance Response or Request instance - * @return Mixed - */ -function clone(instance) { - let p1, p2; - let body = instance.body; +/***/ 8262: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // don't allow cloning a used body - if (instance.bodyUsed) { - throw new Error('cannot clone body after it is used'); - } +"use strict"; - // check that body is a stream and not form-data object - // note: we can't clone the form-data object without having it as a dependency - if (body instanceof Stream && typeof body.getBoundary !== 'function') { - // tee instance body - p1 = new PassThrough(); - p2 = new PassThrough(); - body.pipe(p1); - body.pipe(p2); - // set instance body to teed body and return the other teed body - instance[INTERNALS].body = p1; - body = p2; - } +const usm = __nccwpck_require__(33); - return body; -} +exports.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0]; + const base = constructorArgs[1]; -/** - * Performs the operation "extract a `Content-Type` value from |object|" as - * specified in the specification: - * https://fetch.spec.whatwg.org/#concept-bodyinit-extract - * - * This function assumes that instance.body is present. - * - * @param Mixed instance Any options.body input - */ -function extractContentType(body) { - if (body === null) { - // body is null - return null; - } else if (typeof body === 'string') { - // body is string - return 'text/plain;charset=UTF-8'; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - return 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isBlob(body)) { - // body is blob - return body.type || null; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return null; - } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - return null; - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - return null; - } else if (typeof body.getBoundary === 'function') { - // detect form data input from form-data module - return `multipart/form-data;boundary=${body.getBoundary()}`; - } else if (body instanceof Stream) { - // body is stream - // can't really do much about this - return null; - } else { - // Body constructor defaults other things to string - return 'text/plain;charset=UTF-8'; - } -} + let parsedBase = null; + if (base !== undefined) { + parsedBase = usm.basicURLParse(base); + if (parsedBase === "failure") { + throw new TypeError("Invalid base URL"); + } + } -/** - * The Fetch Standard treats this as if "total bytes" is a property on the body. - * For us, we have to explicitly get it with a function. - * - * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes - * - * @param Body instance Instance of Body - * @return Number? Number of bytes, or null if not possible - */ -function getTotalBytes(instance) { - const body = instance.body; + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } + this._url = parsedURL; - if (body === null) { - // body is null - return 0; - } else if (isBlob(body)) { - return body.size; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return body.length; - } else if (body && typeof body.getLengthSync === 'function') { - // detect form data input from form-data module - if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x - body.hasKnownLength && body.hasKnownLength()) { - // 2.x - return body.getLengthSync(); - } - return null; - } else { - // body is stream - return null; - } -} + // TODO: query stuff + } -/** - * Write a Body to a Node.js WritableStream (e.g. http.Request) object. - * - * @param Body instance Instance of Body - * @return Void - */ -function writeToStream(dest, instance) { - const body = instance.body; + get href() { + return usm.serializeURL(this._url); + } + set href(v) { + const parsedURL = usm.basicURLParse(v); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } - if (body === null) { - // body is null - dest.end(); - } else if (isBlob(body)) { - body.stream().pipe(dest); - } else if (Buffer.isBuffer(body)) { - // body is buffer - dest.write(body); - dest.end(); - } else { - // body is stream - body.pipe(dest); - } -} + this._url = parsedURL; + } -// expose Promise -Body.Promise = global.Promise; + get origin() { + return usm.serializeURLOrigin(this._url); + } -/** - * headers.js - * - * Headers class offers convenient helpers - */ + get protocol() { + return this._url.scheme + ":"; + } -const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; + set protocol(v) { + usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); + } -function validateName(name) { - name = `${name}`; - if (invalidTokenRegex.test(name) || name === '') { - throw new TypeError(`${name} is not a legal HTTP header name`); - } -} + get username() { + return this._url.username; + } -function validateValue(value) { - value = `${value}`; - if (invalidHeaderCharRegex.test(value)) { - throw new TypeError(`${value} is not a legal HTTP header value`); - } -} + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } -/** - * Find the key in the map object given a header name. - * - * Returns undefined if not found. - * - * @param String name Header name - * @return String|Undefined - */ -function find(map, name) { - name = name.toLowerCase(); - for (const key in map) { - if (key.toLowerCase() === name) { - return key; - } - } - return undefined; -} + usm.setTheUsername(this._url, v); + } -const MAP = Symbol('map'); -class Headers { - /** - * Headers class - * - * @param Object headers Response headers - * @return Void - */ - constructor() { - let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + get password() { + return this._url.password; + } - this[MAP] = Object.create(null); + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - if (init instanceof Headers) { - const rawHeaders = init.raw(); - const headerNames = Object.keys(rawHeaders); + usm.setThePassword(this._url, v); + } - for (const headerName of headerNames) { - for (const value of rawHeaders[headerName]) { - this.append(headerName, value); - } - } + get host() { + const url = this._url; - return; - } + if (url.host === null) { + return ""; + } - // We don't worry about converting prop to ByteString here as append() - // will handle it. - if (init == null) ; else if (typeof init === 'object') { - const method = init[Symbol.iterator]; - if (method != null) { - if (typeof method !== 'function') { - throw new TypeError('Header pairs must be iterable'); - } + if (url.port === null) { + return usm.serializeHost(url.host); + } - // sequence> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { - throw new TypeError('Each header pair must be iterable'); - } - pairs.push(Array.from(pair)); - } + return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); + } - for (const pair of pairs) { - if (pair.length !== 2) { - throw new TypeError('Each header pair must be a name/value tuple'); - } - this.append(pair[0], pair[1]); - } - } else { - // record - for (const key of Object.keys(init)) { - const value = init[key]; - this.append(key, value); - } - } - } else { - throw new TypeError('Provided initializer must be an object'); - } - } + set host(v) { + if (this._url.cannotBeABaseURL) { + return; + } - /** - * Return combined header value given name - * - * @param String name Header name - * @return Mixed - */ - get(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key === undefined) { - return null; - } + usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); + } - return this[MAP][key].join(', '); - } + get hostname() { + if (this._url.host === null) { + return ""; + } - /** - * Iterate over all headers - * - * @param Function callback Executed for each item with parameters (value, name, thisArg) - * @param Boolean thisArg `this` context for callback function - * @return Void - */ - forEach(callback) { - let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + return usm.serializeHost(this._url.host); + } - let pairs = getHeaders(this); - let i = 0; - while (i < pairs.length) { - var _pairs$i = pairs[i]; - const name = _pairs$i[0], - value = _pairs$i[1]; + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return; + } - callback.call(thisArg, value, name, this); - pairs = getHeaders(this); - i++; - } - } + usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); + } - /** - * Overwrite header values given name - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - set(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - this[MAP][key !== undefined ? key : name] = [value]; - } + get port() { + if (this._url.port === null) { + return ""; + } - /** - * Append a value onto existing header - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - append(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - if (key !== undefined) { - this[MAP][key].push(value); - } else { - this[MAP][name] = [value]; - } - } + return usm.serializeInteger(this._url.port); + } - /** - * Check for header name existence - * - * @param String name Header name - * @return Boolean - */ - has(name) { - name = `${name}`; - validateName(name); - return find(this[MAP], name) !== undefined; - } + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - /** - * Delete all header values given name - * - * @param String name Header name - * @return Void - */ - delete(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key !== undefined) { - delete this[MAP][key]; - } - } + if (v === "") { + this._url.port = null; + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); + } + } - /** - * Return raw headers (non-spec api) - * - * @return Object - */ - raw() { - return this[MAP]; - } + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0]; + } - /** - * Get an iterator on keys. - * - * @return Iterator - */ - keys() { - return createHeadersIterator(this, 'key'); - } + if (this._url.path.length === 0) { + return ""; + } - /** - * Get an iterator on values. - * - * @return Iterator - */ - values() { - return createHeadersIterator(this, 'value'); - } + return "/" + this._url.path.join("/"); + } - /** - * Get an iterator on entries. - * - * This is the default iterator of the Headers object. - * - * @return Iterator - */ - [Symbol.iterator]() { - return createHeadersIterator(this, 'key+value'); - } -} -Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return; + } -Object.defineProperty(Headers.prototype, Symbol.toStringTag, { - value: 'Headers', - writable: false, - enumerable: false, - configurable: true -}); + this._url.path = []; + usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); + } -Object.defineProperties(Headers.prototype, { - get: { enumerable: true }, - forEach: { enumerable: true }, - set: { enumerable: true }, - append: { enumerable: true }, - has: { enumerable: true }, - delete: { enumerable: true }, - keys: { enumerable: true }, - values: { enumerable: true }, - entries: { enumerable: true } -}); + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } -function getHeaders(headers) { - let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + return "?" + this._url.query; + } - const keys = Object.keys(headers[MAP]).sort(); - return keys.map(kind === 'key' ? function (k) { - return k.toLowerCase(); - } : kind === 'value' ? function (k) { - return headers[MAP][k].join(', '); - } : function (k) { - return [k.toLowerCase(), headers[MAP][k].join(', ')]; - }); -} + set search(v) { + // TODO: query stuff -const INTERNAL = Symbol('internal'); + const url = this._url; -function createHeadersIterator(target, kind) { - const iterator = Object.create(HeadersIteratorPrototype); - iterator[INTERNAL] = { - target, - kind, - index: 0 - }; - return iterator; -} + if (v === "") { + url.query = null; + return; + } -const HeadersIteratorPrototype = Object.setPrototypeOf({ - next() { - // istanbul ignore if - if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { - throw new TypeError('Value of `this` is not a HeadersIterator'); - } - - var _INTERNAL = this[INTERNAL]; - const target = _INTERNAL.target, - kind = _INTERNAL.kind, - index = _INTERNAL.index; + const input = v[0] === "?" ? v.substring(1) : v; + url.query = ""; + usm.basicURLParse(input, { url, stateOverride: "query" }); + } - const values = getHeaders(target, kind); - const len = values.length; - if (index >= len) { - return { - value: undefined, - done: true - }; - } + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } - this[INTERNAL].index = index + 1; + return "#" + this._url.fragment; + } - return { - value: values[index], - done: false - }; - } -}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + set hash(v) { + if (v === "") { + this._url.fragment = null; + return; + } -Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { - value: 'HeadersIterator', - writable: false, - enumerable: false, - configurable: true -}); + const input = v[0] === "#" ? v.substring(1) : v; + this._url.fragment = ""; + usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); + } -/** - * Export the Headers object in a form that Node.js can consume. - * - * @param Headers headers - * @return Object - */ -function exportNodeCompatibleHeaders(headers) { - const obj = Object.assign({ __proto__: null }, headers[MAP]); + toJSON() { + return this.href; + } +}; - // http.request() only supports string as Host header. This hack makes - // specifying custom Host header possible. - const hostHeaderKey = find(headers[MAP], 'Host'); - if (hostHeaderKey !== undefined) { - obj[hostHeaderKey] = obj[hostHeaderKey][0]; - } - return obj; -} +/***/ }), -/** - * Create a Headers object from an object of headers, ignoring those that do - * not conform to HTTP grammar productions. - * - * @param Object obj Object of headers - * @return Headers - */ -function createHeadersLenient(obj) { - const headers = new Headers(); - for (const name of Object.keys(obj)) { - if (invalidTokenRegex.test(name)) { - continue; - } - if (Array.isArray(obj[name])) { - for (const val of obj[name]) { - if (invalidHeaderCharRegex.test(val)) { - continue; - } - if (headers[MAP][name] === undefined) { - headers[MAP][name] = [val]; - } else { - headers[MAP][name].push(val); - } - } - } else if (!invalidHeaderCharRegex.test(obj[name])) { - headers[MAP][name] = [obj[name]]; - } - } - return headers; -} +/***/ 653: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const INTERNALS$1 = Symbol('Response internals'); +"use strict"; -// fix an issue where "STATUS_CODES" aren't a named export for node <10 -const STATUS_CODES = http.STATUS_CODES; -/** - * Response class - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -class Response { - constructor() { - let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +const conversions = __nccwpck_require__(5871); +const utils = __nccwpck_require__(276); +const Impl = __nccwpck_require__(8262); - Body.call(this, body, opts); +const impl = utils.implSymbol; - const status = opts.status || 200; - const headers = new Headers(opts.headers); +function URL(url) { + if (!this || this[impl] || !(this instanceof URL)) { + throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); + } + if (arguments.length < 1) { + throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); + } + const args = []; + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i]; + } + args[0] = conversions["USVString"](args[0]); + if (args[1] !== undefined) { + args[1] = conversions["USVString"](args[1]); + } - if (body != null && !headers.has('Content-Type')) { - const contentType = extractContentType(body); - if (contentType) { - headers.append('Content-Type', contentType); - } - } + module.exports.setup(this, args); +} - this[INTERNALS$1] = { - url: opts.url, - status, - statusText: opts.statusText || STATUS_CODES[status], - headers, - counter: opts.counter - }; - } +URL.prototype.toJSON = function toJSON() { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + const args = []; + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i]; + } + return this[impl].toJSON.apply(this[impl], args); +}; +Object.defineProperty(URL.prototype, "href", { + get() { + return this[impl].href; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].href = V; + }, + enumerable: true, + configurable: true +}); - get url() { - return this[INTERNALS$1].url || ''; - } +URL.prototype.toString = function () { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + return this.href; +}; - get status() { - return this[INTERNALS$1].status; - } +Object.defineProperty(URL.prototype, "origin", { + get() { + return this[impl].origin; + }, + enumerable: true, + configurable: true +}); - /** - * Convenience property representing if the request ended normally - */ - get ok() { - return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; - } +Object.defineProperty(URL.prototype, "protocol", { + get() { + return this[impl].protocol; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].protocol = V; + }, + enumerable: true, + configurable: true +}); - get redirected() { - return this[INTERNALS$1].counter > 0; - } +Object.defineProperty(URL.prototype, "username", { + get() { + return this[impl].username; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].username = V; + }, + enumerable: true, + configurable: true +}); - get statusText() { - return this[INTERNALS$1].statusText; - } +Object.defineProperty(URL.prototype, "password", { + get() { + return this[impl].password; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].password = V; + }, + enumerable: true, + configurable: true +}); - get headers() { - return this[INTERNALS$1].headers; - } +Object.defineProperty(URL.prototype, "host", { + get() { + return this[impl].host; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].host = V; + }, + enumerable: true, + configurable: true +}); - /** - * Clone this response - * - * @return Response - */ - clone() { - return new Response(clone(this), { - url: this.url, - status: this.status, - statusText: this.statusText, - headers: this.headers, - ok: this.ok, - redirected: this.redirected - }); - } -} - -Body.mixIn(Response.prototype); - -Object.defineProperties(Response.prototype, { - url: { enumerable: true }, - status: { enumerable: true }, - ok: { enumerable: true }, - redirected: { enumerable: true }, - statusText: { enumerable: true }, - headers: { enumerable: true }, - clone: { enumerable: true } +Object.defineProperty(URL.prototype, "hostname", { + get() { + return this[impl].hostname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hostname = V; + }, + enumerable: true, + configurable: true }); -Object.defineProperty(Response.prototype, Symbol.toStringTag, { - value: 'Response', - writable: false, - enumerable: false, - configurable: true +Object.defineProperty(URL.prototype, "port", { + get() { + return this[impl].port; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].port = V; + }, + enumerable: true, + configurable: true }); -const INTERNALS$2 = Symbol('Request internals'); -const URL = Url.URL || whatwgUrl.URL; - -// fix an issue where "format", "parse" aren't a named export for node <10 -const parse_url = Url.parse; -const format_url = Url.format; - -/** - * Wrapper around `new URL` to handle arbitrary URLs - * - * @param {string} urlStr - * @return {void} - */ -function parseURL(urlStr) { - /* - Check whether the URL is absolute or not - Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 - Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 - */ - if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { - urlStr = new URL(urlStr).toString(); - } - - // Fallback to old implementation for arbitrary URLs - return parse_url(urlStr); -} - -const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; - -/** - * Check if a value is an instance of Request. - * - * @param Mixed input - * @return Boolean - */ -function isRequest(input) { - return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; -} - -function isAbortSignal(signal) { - const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); - return !!(proto && proto.constructor.name === 'AbortSignal'); -} - -/** - * Request class - * - * @param Mixed input Url or Request instance - * @param Object init Custom options - * @return Void - */ -class Request { - constructor(input) { - let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - let parsedURL; - - // normalize input - if (!isRequest(input)) { - if (input && input.href) { - // in order to support Node.js' Url objects; though WHATWG's URL objects - // will fall into this branch also (since their `toString()` will return - // `href` property anyway) - parsedURL = parseURL(input.href); - } else { - // coerce input to a string before attempting to parse - parsedURL = parseURL(`${input}`); - } - input = {}; - } else { - parsedURL = parseURL(input.url); - } - - let method = init.method || input.method || 'GET'; - method = method.toUpperCase(); - - if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { - throw new TypeError('Request with GET/HEAD method cannot have body'); - } +Object.defineProperty(URL.prototype, "pathname", { + get() { + return this[impl].pathname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].pathname = V; + }, + enumerable: true, + configurable: true +}); - let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; +Object.defineProperty(URL.prototype, "search", { + get() { + return this[impl].search; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].search = V; + }, + enumerable: true, + configurable: true +}); - Body.call(this, inputBody, { - timeout: init.timeout || input.timeout || 0, - size: init.size || input.size || 0 - }); +Object.defineProperty(URL.prototype, "hash", { + get() { + return this[impl].hash; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hash = V; + }, + enumerable: true, + configurable: true +}); - const headers = new Headers(init.headers || input.headers || {}); - if (inputBody != null && !headers.has('Content-Type')) { - const contentType = extractContentType(inputBody); - if (contentType) { - headers.append('Content-Type', contentType); - } - } +module.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation; + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL.prototype); + this.setup(obj, constructorArgs, privateData); + return obj; + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {}; + privateData.wrapper = obj; - let signal = isRequest(input) ? input.signal : null; - if ('signal' in init) signal = init.signal; + obj[impl] = new Impl.implementation(constructorArgs, privateData); + obj[impl][utils.wrapperSymbol] = obj; + }, + interface: URL, + expose: { + Window: { URL: URL }, + Worker: { URL: URL } + } +}; - if (signal != null && !isAbortSignal(signal)) { - throw new TypeError('Expected signal to be an instanceof AbortSignal'); - } - this[INTERNALS$2] = { - method, - redirect: init.redirect || input.redirect || 'follow', - headers, - parsedURL, - signal - }; - // node-fetch-only options - this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; - this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; - this.counter = init.counter || input.counter || 0; - this.agent = init.agent || input.agent; - } +/***/ }), - get method() { - return this[INTERNALS$2].method; - } +/***/ 3323: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - get url() { - return format_url(this[INTERNALS$2].parsedURL); - } +"use strict"; - get headers() { - return this[INTERNALS$2].headers; - } - get redirect() { - return this[INTERNALS$2].redirect; - } +exports.URL = __nccwpck_require__(653)["interface"]; +exports.serializeURL = __nccwpck_require__(33).serializeURL; +exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; +exports.basicURLParse = __nccwpck_require__(33).basicURLParse; +exports.setTheUsername = __nccwpck_require__(33).setTheUsername; +exports.setThePassword = __nccwpck_require__(33).setThePassword; +exports.serializeHost = __nccwpck_require__(33).serializeHost; +exports.serializeInteger = __nccwpck_require__(33).serializeInteger; +exports.parseURL = __nccwpck_require__(33).parseURL; - get signal() { - return this[INTERNALS$2].signal; - } - /** - * Clone this request - * - * @return Request - */ - clone() { - return new Request(this); - } -} +/***/ }), -Body.mixIn(Request.prototype); - -Object.defineProperty(Request.prototype, Symbol.toStringTag, { - value: 'Request', - writable: false, - enumerable: false, - configurable: true -}); - -Object.defineProperties(Request.prototype, { - method: { enumerable: true }, - url: { enumerable: true }, - headers: { enumerable: true }, - redirect: { enumerable: true }, - clone: { enumerable: true }, - signal: { enumerable: true } -}); - -/** - * Convert a Request to Node.js http request options. - * - * @param Request A Request instance - * @return Object The options object to be passed to http.request - */ -function getNodeRequestOptions(request) { - const parsedURL = request[INTERNALS$2].parsedURL; - const headers = new Headers(request[INTERNALS$2].headers); - - // fetch step 1.3 - if (!headers.has('Accept')) { - headers.set('Accept', '*/*'); - } - - // Basic fetch - if (!parsedURL.protocol || !parsedURL.hostname) { - throw new TypeError('Only absolute URLs are supported'); - } - - if (!/^https?:$/.test(parsedURL.protocol)) { - throw new TypeError('Only HTTP(S) protocols are supported'); - } - - if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { - throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); - } - - // HTTP-network-or-cache fetch steps 2.4-2.7 - let contentLengthValue = null; - if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { - contentLengthValue = '0'; - } - if (request.body != null) { - const totalBytes = getTotalBytes(request); - if (typeof totalBytes === 'number') { - contentLengthValue = String(totalBytes); - } - } - if (contentLengthValue) { - headers.set('Content-Length', contentLengthValue); - } - - // HTTP-network-or-cache fetch step 2.11 - if (!headers.has('User-Agent')) { - headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); - } - - // HTTP-network-or-cache fetch step 2.15 - if (request.compress && !headers.has('Accept-Encoding')) { - headers.set('Accept-Encoding', 'gzip,deflate'); - } - - let agent = request.agent; - if (typeof agent === 'function') { - agent = agent(parsedURL); - } - - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close'); - } - - // HTTP-network fetch step 4.2 - // chunked encoding is handled by Node.js - - return Object.assign({}, parsedURL, { - method: request.method, - headers: exportNodeCompatibleHeaders(headers), - agent - }); -} - -/** - * abort-error.js - * - * AbortError interface for cancelled requests - */ - -/** - * Create AbortError instance - * - * @param String message Error message for human - * @return AbortError - */ -function AbortError(message) { - Error.call(this, message); - - this.type = 'aborted'; - this.message = message; - - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} - -AbortError.prototype = Object.create(Error.prototype); -AbortError.prototype.constructor = AbortError; -AbortError.prototype.name = 'AbortError'; - -const URL$1 = Url.URL || whatwgUrl.URL; - -// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 -const PassThrough$1 = Stream.PassThrough; - -const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { - const orig = new URL$1(original).hostname; - const dest = new URL$1(destination).hostname; - - return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); -}; - -/** - * Fetch function - * - * @param Mixed url Absolute url or Request instance - * @param Object opts Fetch options - * @return Promise - */ -function fetch(url, opts) { - - // allow custom promise - if (!fetch.Promise) { - throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); - } - - Body.Promise = fetch.Promise; - - // wrap http.request into fetch - return new fetch.Promise(function (resolve, reject) { - // build request object - const request = new Request(url, opts); - const options = getNodeRequestOptions(request); - - const send = (options.protocol === 'https:' ? https : http).request; - const signal = request.signal; - - let response = null; - - const abort = function abort() { - let error = new AbortError('The user aborted a request.'); - reject(error); - if (request.body && request.body instanceof Stream.Readable) { - request.body.destroy(error); - } - if (!response || !response.body) return; - response.body.emit('error', error); - }; - - if (signal && signal.aborted) { - abort(); - return; - } - - const abortAndFinalize = function abortAndFinalize() { - abort(); - finalize(); - }; - - // send request - const req = send(options); - let reqTimeout; - - if (signal) { - signal.addEventListener('abort', abortAndFinalize); - } - - function finalize() { - req.abort(); - if (signal) signal.removeEventListener('abort', abortAndFinalize); - clearTimeout(reqTimeout); - } - - if (request.timeout) { - req.once('socket', function (socket) { - reqTimeout = setTimeout(function () { - reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); - finalize(); - }, request.timeout); - }); - } - - req.on('error', function (err) { - reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); - finalize(); - }); - - req.on('response', function (res) { - clearTimeout(reqTimeout); - - const headers = createHeadersLenient(res.headers); - - // HTTP fetch step 5 - if (fetch.isRedirect(res.statusCode)) { - // HTTP fetch step 5.2 - const location = headers.get('Location'); - - // HTTP fetch step 5.3 - let locationURL = null; - try { - locationURL = location === null ? null : new URL$1(location, request.url).toString(); - } catch (err) { - // error here can only be invalid URL in Location: header - // do not throw when options.redirect == manual - // let the user extract the errorneous redirect URL - if (request.redirect !== 'manual') { - reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); - finalize(); - return; - } - } - - // HTTP fetch step 5.5 - switch (request.redirect) { - case 'error': - reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); - finalize(); - return; - case 'manual': - // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. - if (locationURL !== null) { - // handle corrupted header - try { - headers.set('Location', locationURL); - } catch (err) { - // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request - reject(err); - } - } - break; - case 'follow': - // HTTP-redirect fetch step 2 - if (locationURL === null) { - break; - } - - // HTTP-redirect fetch step 5 - if (request.counter >= request.follow) { - reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 6 (counter increment) - // Create a new Request object. - const requestOpts = { - headers: new Headers(request.headers), - follow: request.follow, - counter: request.counter + 1, - agent: request.agent, - compress: request.compress, - method: request.method, - body: request.body, - signal: request.signal, - timeout: request.timeout, - size: request.size - }; - - if (!isDomainOrSubdomain(request.url, locationURL)) { - for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { - requestOpts.headers.delete(name); - } - } - - // HTTP-redirect fetch step 9 - if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { - reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 11 - if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { - requestOpts.method = 'GET'; - requestOpts.body = undefined; - requestOpts.headers.delete('content-length'); - } - - // HTTP-redirect fetch step 15 - resolve(fetch(new Request(locationURL, requestOpts))); - finalize(); - return; - } - } - - // prepare response - res.once('end', function () { - if (signal) signal.removeEventListener('abort', abortAndFinalize); - }); - let body = res.pipe(new PassThrough$1()); - - const response_options = { - url: request.url, - status: res.statusCode, - statusText: res.statusMessage, - headers: headers, - size: request.size, - timeout: request.timeout, - counter: request.counter - }; - - // HTTP-network fetch step 12.1.1.3 - const codings = headers.get('Content-Encoding'); - - // HTTP-network fetch step 12.1.1.4: handle content codings - - // in following scenarios we ignore compression support - // 1. compression support is disabled - // 2. HEAD request - // 3. no Content-Encoding header - // 4. no content response (204) - // 5. content not modified response (304) - if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { - response = new Response(body, response_options); - resolve(response); - return; - } - - // For Node v6+ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - const zlibOptions = { - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH - }; - - // for gzip - if (codings == 'gzip' || codings == 'x-gzip') { - body = body.pipe(zlib.createGunzip(zlibOptions)); - response = new Response(body, response_options); - resolve(response); - return; - } - - // for deflate - if (codings == 'deflate' || codings == 'x-deflate') { - // handle the infamous raw deflate response from old servers - // a hack for old IIS and Apache servers - const raw = res.pipe(new PassThrough$1()); - raw.once('data', function (chunk) { - // see http://stackoverflow.com/questions/37519828 - if ((chunk[0] & 0x0F) === 0x08) { - body = body.pipe(zlib.createInflate()); - } else { - body = body.pipe(zlib.createInflateRaw()); - } - response = new Response(body, response_options); - resolve(response); - }); - return; - } - - // for br - if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { - body = body.pipe(zlib.createBrotliDecompress()); - response = new Response(body, response_options); - resolve(response); - return; - } - - // otherwise, use response as-is - response = new Response(body, response_options); - resolve(response); - }); - - writeToStream(req, request); - }); -} -/** - * Redirect code matching - * - * @param Number code Status code - * @return Boolean - */ -fetch.isRedirect = function (code) { - return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; -}; - -// expose Promise -fetch.Promise = global.Promise; - -module.exports = exports = fetch; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports; -exports.Headers = Headers; -exports.Request = Request; -exports.Response = Response; -exports.FetchError = FetchError; - - -/***/ }), - -/***/ 2299: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -var punycode = __nccwpck_require__(5477); -var mappingTable = __nccwpck_require__(1907); - -var PROCESSING_OPTIONS = { - TRANSITIONAL: 0, - NONTRANSITIONAL: 1 -}; - -function normalize(str) { // fix bug in v8 - return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); -} - -function findStatus(val) { - var start = 0; - var end = mappingTable.length - 1; - - while (start <= end) { - var mid = Math.floor((start + end) / 2); - - var target = mappingTable[mid]; - if (target[0][0] <= val && target[0][1] >= val) { - return target; - } else if (target[0][0] > val) { - end = mid - 1; - } else { - start = mid + 1; - } - } - - return null; -} - -var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; - -function countSymbols(string) { - return string - // replace every surrogate pair with a BMP symbol - .replace(regexAstralSymbols, '_') - // then get the length - .length; -} - -function mapChars(domain_name, useSTD3, processing_option) { - var hasError = false; - var processed = ""; - - var len = countSymbols(domain_name); - for (var i = 0; i < len; ++i) { - var codePoint = domain_name.codePointAt(i); - var status = findStatus(codePoint); - - switch (status[1]) { - case "disallowed": - hasError = true; - processed += String.fromCodePoint(codePoint); - break; - case "ignored": - break; - case "mapped": - processed += String.fromCodePoint.apply(String, status[2]); - break; - case "deviation": - if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { - processed += String.fromCodePoint.apply(String, status[2]); - } else { - processed += String.fromCodePoint(codePoint); - } - break; - case "valid": - processed += String.fromCodePoint(codePoint); - break; - case "disallowed_STD3_mapped": - if (useSTD3) { - hasError = true; - processed += String.fromCodePoint(codePoint); - } else { - processed += String.fromCodePoint.apply(String, status[2]); - } - break; - case "disallowed_STD3_valid": - if (useSTD3) { - hasError = true; - } - - processed += String.fromCodePoint(codePoint); - break; - } - } - - return { - string: processed, - error: hasError - }; -} - -var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; - -function validateLabel(label, processing_option) { - if (label.substr(0, 4) === "xn--") { - label = punycode.toUnicode(label); - processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; - } - - var error = false; - - if (normalize(label) !== label || - (label[3] === "-" && label[4] === "-") || - label[0] === "-" || label[label.length - 1] === "-" || - label.indexOf(".") !== -1 || - label.search(combiningMarksRegex) === 0) { - error = true; - } - - var len = countSymbols(label); - for (var i = 0; i < len; ++i) { - var status = findStatus(label.codePointAt(i)); - if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || - (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && - status[1] !== "valid" && status[1] !== "deviation")) { - error = true; - break; - } - } - - return { - label: label, - error: error - }; -} - -function processing(domain_name, useSTD3, processing_option) { - var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize(result.string); - - var labels = result.string.split("."); - for (var i = 0; i < labels.length; ++i) { - try { - var validation = validateLabel(labels[i]); - labels[i] = validation.label; - result.error = result.error || validation.error; - } catch(e) { - result.error = true; - } - } - - return { - string: labels.join("."), - error: result.error - }; -} - -module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { - var result = processing(domain_name, useSTD3, processing_option); - var labels = result.string.split("."); - labels = labels.map(function(l) { - try { - return punycode.toASCII(l); - } catch(e) { - result.error = true; - return l; - } - }); - - if (verifyDnsLength) { - var total = labels.slice(0, labels.length - 1).join(".").length; - if (total.length > 253 || total.length === 0) { - result.error = true; - } - - for (var i=0; i < labels.length; ++i) { - if (labels.length > 63 || labels.length === 0) { - result.error = true; - break; - } - } - } - - if (result.error) return null; - return labels.join("."); -}; - -module.exports.toUnicode = function(domain_name, useSTD3) { - var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - - return { - domain: result.string, - error: result.error - }; -}; - -module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - - -/***/ }), - -/***/ 5871: -/***/ ((module) => { - -"use strict"; - - -var conversions = {}; -module.exports = conversions; - -function sign(x) { - return x < 0 ? -1 : 1; -} - -function evenRound(x) { - // Round x to the nearest integer, choosing the even integer if it lies halfway between two. - if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) - return Math.floor(x); - } else { - return Math.round(x); - } -} - -function createNumberConversion(bitLength, typeOpts) { - if (!typeOpts.unsigned) { - --bitLength; - } - const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); - const upperBound = Math.pow(2, bitLength) - 1; - - const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); - const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - - return function(V, opts) { - if (!opts) opts = {}; - - let x = +V; - - if (opts.enforceRange) { - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite number"); - } - - x = sign(x) * Math.floor(Math.abs(x)); - if (x < lowerBound || x > upperBound) { - throw new TypeError("Argument is not in byte range"); - } - - return x; - } - - if (!isNaN(x) && opts.clamp) { - x = evenRound(x); - - if (x < lowerBound) x = lowerBound; - if (x > upperBound) x = upperBound; - return x; - } - - if (!Number.isFinite(x) || x === 0) { - return 0; - } - - x = sign(x) * Math.floor(Math.abs(x)); - x = x % moduloVal; - - if (!typeOpts.unsigned && x >= moduloBound) { - return x - moduloVal; - } else if (typeOpts.unsigned) { - if (x < 0) { - x += moduloVal; - } else if (x === -0) { // don't return negative zero - return 0; - } - } - - return x; - } -} - -conversions["void"] = function () { - return undefined; -}; - -conversions["boolean"] = function (val) { - return !!val; -}; - -conversions["byte"] = createNumberConversion(8, { unsigned: false }); -conversions["octet"] = createNumberConversion(8, { unsigned: true }); - -conversions["short"] = createNumberConversion(16, { unsigned: false }); -conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - -conversions["long"] = createNumberConversion(32, { unsigned: false }); -conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - -conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); -conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - -conversions["double"] = function (V) { - const x = +V; - - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite floating-point value"); - } - - return x; -}; - -conversions["unrestricted double"] = function (V) { - const x = +V; - - if (isNaN(x)) { - throw new TypeError("Argument is NaN"); - } - - return x; -}; - -// not quite valid, but good enough for JS -conversions["float"] = conversions["double"]; -conversions["unrestricted float"] = conversions["unrestricted double"]; - -conversions["DOMString"] = function (V, opts) { - if (!opts) opts = {}; - - if (opts.treatNullAsEmptyString && V === null) { - return ""; - } - - return String(V); -}; - -conversions["ByteString"] = function (V, opts) { - const x = String(V); - let c = undefined; - for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { - if (c > 255) { - throw new TypeError("Argument is not a valid bytestring"); - } - } - - return x; -}; - -conversions["USVString"] = function (V) { - const S = String(V); - const n = S.length; - const U = []; - for (let i = 0; i < n; ++i) { - const c = S.charCodeAt(i); - if (c < 0xD800 || c > 0xDFFF) { - U.push(String.fromCodePoint(c)); - } else if (0xDC00 <= c && c <= 0xDFFF) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - if (i === n - 1) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - const d = S.charCodeAt(i + 1); - if (0xDC00 <= d && d <= 0xDFFF) { - const a = c & 0x3FF; - const b = d & 0x3FF; - U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); - ++i; - } else { - U.push(String.fromCodePoint(0xFFFD)); - } - } - } - } - - return U.join(''); -}; - -conversions["Date"] = function (V, opts) { - if (!(V instanceof Date)) { - throw new TypeError("Argument is not a Date object"); - } - if (isNaN(V)) { - return undefined; - } - - return V; -}; - -conversions["RegExp"] = function (V, opts) { - if (!(V instanceof RegExp)) { - V = new RegExp(V); - } - - return V; -}; - - -/***/ }), - -/***/ 8262: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -const usm = __nccwpck_require__(33); - -exports.implementation = class URLImpl { - constructor(constructorArgs) { - const url = constructorArgs[0]; - const base = constructorArgs[1]; - - let parsedBase = null; - if (base !== undefined) { - parsedBase = usm.basicURLParse(base); - if (parsedBase === "failure") { - throw new TypeError("Invalid base URL"); - } - } - - const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - - // TODO: query stuff - } - - get href() { - return usm.serializeURL(this._url); - } - - set href(v) { - const parsedURL = usm.basicURLParse(v); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - } - - get origin() { - return usm.serializeURLOrigin(this._url); - } - - get protocol() { - return this._url.scheme + ":"; - } - - set protocol(v) { - usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); - } - - get username() { - return this._url.username; - } - - set username(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setTheUsername(this._url, v); - } - - get password() { - return this._url.password; - } - - set password(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setThePassword(this._url, v); - } - - get host() { - const url = this._url; - - if (url.host === null) { - return ""; - } - - if (url.port === null) { - return usm.serializeHost(url.host); - } - - return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); - } - - set host(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); - } - - get hostname() { - if (this._url.host === null) { - return ""; - } - - return usm.serializeHost(this._url.host); - } - - set hostname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); - } - - get port() { - if (this._url.port === null) { - return ""; - } - - return usm.serializeInteger(this._url.port); - } - - set port(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - if (v === "") { - this._url.port = null; - } else { - usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); - } - } - - get pathname() { - if (this._url.cannotBeABaseURL) { - return this._url.path[0]; - } - - if (this._url.path.length === 0) { - return ""; - } - - return "/" + this._url.path.join("/"); - } - - set pathname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - this._url.path = []; - usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); - } - - get search() { - if (this._url.query === null || this._url.query === "") { - return ""; - } - - return "?" + this._url.query; - } - - set search(v) { - // TODO: query stuff - - const url = this._url; - - if (v === "") { - url.query = null; - return; - } - - const input = v[0] === "?" ? v.substring(1) : v; - url.query = ""; - usm.basicURLParse(input, { url, stateOverride: "query" }); - } - - get hash() { - if (this._url.fragment === null || this._url.fragment === "") { - return ""; - } - - return "#" + this._url.fragment; - } - - set hash(v) { - if (v === "") { - this._url.fragment = null; - return; - } - - const input = v[0] === "#" ? v.substring(1) : v; - this._url.fragment = ""; - usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); - } - - toJSON() { - return this.href; - } -}; - - -/***/ }), - -/***/ 653: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const conversions = __nccwpck_require__(5871); -const utils = __nccwpck_require__(276); -const Impl = __nccwpck_require__(8262); - -const impl = utils.implSymbol; - -function URL(url) { - if (!this || this[impl] || !(this instanceof URL)) { - throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); - } - if (arguments.length < 1) { - throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); - } - const args = []; - for (let i = 0; i < arguments.length && i < 2; ++i) { - args[i] = arguments[i]; - } - args[0] = conversions["USVString"](args[0]); - if (args[1] !== undefined) { - args[1] = conversions["USVString"](args[1]); - } - - module.exports.setup(this, args); -} - -URL.prototype.toJSON = function toJSON() { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - const args = []; - for (let i = 0; i < arguments.length && i < 0; ++i) { - args[i] = arguments[i]; - } - return this[impl].toJSON.apply(this[impl], args); -}; -Object.defineProperty(URL.prototype, "href", { - get() { - return this[impl].href; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].href = V; - }, - enumerable: true, - configurable: true -}); - -URL.prototype.toString = function () { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - return this.href; -}; - -Object.defineProperty(URL.prototype, "origin", { - get() { - return this[impl].origin; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "protocol", { - get() { - return this[impl].protocol; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].protocol = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "username", { - get() { - return this[impl].username; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].username = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "password", { - get() { - return this[impl].password; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].password = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "host", { - get() { - return this[impl].host; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].host = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hostname", { - get() { - return this[impl].hostname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hostname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "port", { - get() { - return this[impl].port; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].port = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "pathname", { - get() { - return this[impl].pathname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].pathname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "search", { - get() { - return this[impl].search; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].search = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hash", { - get() { - return this[impl].hash; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hash = V; - }, - enumerable: true, - configurable: true -}); - - -module.exports = { - is(obj) { - return !!obj && obj[impl] instanceof Impl.implementation; - }, - create(constructorArgs, privateData) { - let obj = Object.create(URL.prototype); - this.setup(obj, constructorArgs, privateData); - return obj; - }, - setup(obj, constructorArgs, privateData) { - if (!privateData) privateData = {}; - privateData.wrapper = obj; - - obj[impl] = new Impl.implementation(constructorArgs, privateData); - obj[impl][utils.wrapperSymbol] = obj; - }, - interface: URL, - expose: { - Window: { URL: URL }, - Worker: { URL: URL } - } -}; - - - -/***/ }), - -/***/ 3323: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -exports.URL = __nccwpck_require__(653)["interface"]; -exports.serializeURL = __nccwpck_require__(33).serializeURL; -exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; -exports.basicURLParse = __nccwpck_require__(33).basicURLParse; -exports.setTheUsername = __nccwpck_require__(33).setTheUsername; -exports.setThePassword = __nccwpck_require__(33).setThePassword; -exports.serializeHost = __nccwpck_require__(33).serializeHost; -exports.serializeInteger = __nccwpck_require__(33).serializeInteger; -exports.parseURL = __nccwpck_require__(33).parseURL; - - -/***/ }), - -/***/ 33: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 33: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; @@ -15619,478 +13468,811 @@ module.exports.parseURL = function (input, options) { }; -/***/ }), +/***/ }), + +/***/ 276: +/***/ ((module) => { + +"use strict"; + + +module.exports.mixin = function mixin(target, source) { + const keys = Object.getOwnPropertyNames(source); + for (let i = 0; i < keys.length; ++i) { + Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); + } +}; + +module.exports.wrapperSymbol = Symbol("wrapper"); +module.exports.implSymbol = Symbol("impl"); + +module.exports.wrapperForImpl = function (impl) { + return impl[module.exports.wrapperSymbol]; +}; + +module.exports.implForWrapper = function (wrapper) { + return wrapper[module.exports.implSymbol]; +}; + + + +/***/ }), + +/***/ 1223: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var wrappy = __nccwpck_require__(2940) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + + +/***/ }), + +/***/ 4294: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = __nccwpck_require__(4219); + + +/***/ }), + +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), + +/***/ 5030: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function getUserAgent() { + if (typeof navigator === "object" && "userAgent" in navigator) { + return navigator.userAgent; + } + + if (typeof process === "object" && "version" in process) { + return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; + } + + return ""; +} + +exports.getUserAgent = getUserAgent; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); -/***/ 276: -/***/ ((module) => { +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); -"use strict"; +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); -module.exports.mixin = function mixin(target, source) { - const keys = Object.getOwnPropertyNames(source); - for (let i = 0; i < keys.length; ++i) { - Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); - } -}; +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); -module.exports.wrapperSymbol = Symbol("wrapper"); -module.exports.implSymbol = Symbol("impl"); +var _version = _interopRequireDefault(__nccwpck_require__(1595)); -module.exports.wrapperForImpl = function (impl) { - return impl[module.exports.wrapperSymbol]; -}; +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -module.exports.implForWrapper = function (wrapper) { - return wrapper[module.exports.implSymbol]; -}; +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), -/***/ 1223: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var wrappy = __nccwpck_require__(2940) -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) +"use strict"; -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f + + return _crypto.default.createHash('md5').update(bytes).digest(); } +var _default = md5; +exports["default"] = _default; /***/ }), -/***/ 4294: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; -module.exports = __nccwpck_require__(4219); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; /***/ }), -/***/ 4219: +/***/ 2746: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var net = __nccwpck_require__(1808); -var tls = __nccwpck_require__(4404); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var events = __nccwpck_require__(2361); -var assert = __nccwpck_require__(9491); -var util = __nccwpck_require__(3837); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; -} + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; } +var _default = parse; +exports["default"] = _default; -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; +/***/ }), - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } - } - socket.destroy(); - self.removeSocket(socket); - }); -} -util.inherits(TunnelingAgent, events.EventEmitter); +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); +"use strict"; - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; + +/***/ }), + +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; + +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); + + poolPtr = 0; } - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} - function onFree() { - self.emit('free', socket, options); - } +/***/ }), + +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; +"use strict"; -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false, - headers: { - host: options.host + ':' + options.port - } - }); - if (options.localAddress) { - connectOptions.localAddress = options.localAddress; - } - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); } - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); + return _crypto.default.createHash('sha1').update(bytes).digest(); +} - if (res.statusCode !== 200) { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - socket.destroy(); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - if (head.length > 0) { - debug('got illegal response body from proxy'); - socket.destroy(); - var error = new Error('got illegal response body from proxy'); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - return cb(socket); - } +var _default = sha1; +exports["default"] = _default; - function onError(cause) { - connectReq.removeAllListeners(); +/***/ }), - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; - } - this.sockets.splice(pos, 1); +"use strict"; - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); - } -}; -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); - }); -} +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; - } - return host; // for v0.11 or later -} +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } - } - return target; +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); } +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); - } - console.error.apply(console, args); + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); } -} else { - debug = function() {}; + + return uuid; } -exports.debug = debug; // for test +var _default = stringify; +exports["default"] = _default; /***/ }), -/***/ 5030: -/***/ ((__unused_webpack_module, exports) => { +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -function getUserAgent() { - if (typeof navigator === "object" && "userAgent" in navigator) { - return navigator.userAgent; - } +var _rng = _interopRequireDefault(__nccwpck_require__(807)); - if (typeof process === "object" && "version" in process) { - return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; - } +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - return ""; -} -exports.getUserAgent = getUserAgent; -//# sourceMappingURL=index.js.map + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) -/***/ }), + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression -/***/ 5840: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval -"use strict"; + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -Object.defineProperty(exports, "v1", ({ - enumerable: true, - get: function () { - return _v.default; - } -})); -Object.defineProperty(exports, "v3", ({ - enumerable: true, - get: function () { - return _v2.default; - } -})); -Object.defineProperty(exports, "v4", ({ - enumerable: true, - get: function () { - return _v3.default; - } -})); -Object.defineProperty(exports, "v5", ({ - enumerable: true, - get: function () { - return _v4.default; - } -})); -Object.defineProperty(exports, "NIL", ({ - enumerable: true, - get: function () { - return _nil.default; - } -})); -Object.defineProperty(exports, "version", ({ - enumerable: true, - get: function () { - return _version.default; - } -})); -Object.defineProperty(exports, "validate", ({ - enumerable: true, - get: function () { - return _validate.default; - } -})); -Object.defineProperty(exports, "stringify", ({ - enumerable: true, - get: function () { - return _stringify.default; - } -})); -Object.defineProperty(exports, "parse", ({ - enumerable: true, - get: function () { - return _parse.default; + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); } -})); -var _v = _interopRequireDefault(__nccwpck_require__(8628)); + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch -var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); + msecs += 12219292800000; // `time_low` -var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` -var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` -var _nil = _interopRequireDefault(__nccwpck_require__(5332)); + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version -var _version = _interopRequireDefault(__nccwpck_require__(1595)); + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + b[i++] = clockseq & 0xff; // `node` -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return buf || (0, _stringify.default)(b); +} + +var _default = v1; +exports["default"] = _default; /***/ }), -/***/ 4569: +/***/ 6409: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -16101,27 +14283,20 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _v = _interopRequireDefault(__nccwpck_require__(5998)); -function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } +var _md = _interopRequireDefault(__nccwpck_require__(4569)); - return _crypto.default.createHash('md5').update(bytes).digest(); -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _default = md5; +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; exports["default"] = _default; /***/ }), -/***/ 5332: -/***/ ((__unused_webpack_module, exports) => { +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -16129,80 +14304,83 @@ exports["default"] = _default; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = void 0; -var _default = '00000000-0000-0000-0000-000000000000'; exports["default"] = _default; +exports.URL = exports.DNS = void 0; -/***/ }), +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); -/***/ 2746: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -"use strict"; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + const bytes = []; -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return bytes; +} -function parse(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; - let v; - const arr = new Uint8Array(16); // Parse ########-....-....-....-............ +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 0xff; - arr[2] = v >>> 8 & 0xff; - arr[3] = v & 0xff; // Parse ........-####-....-....-............ + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 0xff; // Parse ........-....-####-....-............ + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 0xff; // Parse ........-....-....-####-............ - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 0xff; // Parse ........-....-....-....-############ - // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; - arr[11] = v / 0x100000000 & 0xff; - arr[12] = v >>> 24 & 0xff; - arr[13] = v >>> 16 & 0xff; - arr[14] = v >>> 8 & 0xff; - arr[15] = v & 0xff; - return arr; -} + if (buf) { + offset = offset || 0; -var _default = parse; -exports["default"] = _default; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } -/***/ }), + return buf; + } -/***/ 814: -/***/ ((__unused_webpack_module, exports) => { + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) -"use strict"; + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; -exports["default"] = _default; + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} /***/ }), -/***/ 807: +/***/ 5122: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -16211,29 +14389,42 @@ exports["default"] = _default; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = rng; +exports["default"] = void 0; -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate +function v4(options, buf, offset) { + options = options || {}; -let poolPtr = rnds8Pool.length; + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` -function rng() { - if (poolPtr > rnds8Pool.length - 16) { - _crypto.default.randomFillSync(rnds8Pool); - poolPtr = 0; + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; } - return rnds8Pool.slice(poolPtr, poolPtr += 16); + return (0, _stringify.default)(rnds); } +var _default = v4; +exports["default"] = _default; + /***/ }), -/***/ 5274: +/***/ 9120: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -16244,26 +14435,19 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _v = _interopRequireDefault(__nccwpck_require__(5998)); -function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - return _crypto.default.createHash('sha1').update(bytes).digest(); -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _default = sha1; +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; exports["default"] = _default; /***/ }), -/***/ 8950: +/***/ 6900: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -16274,42 +14458,20 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +var _regex = _interopRequireDefault(__nccwpck_require__(814)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -const byteToHex = []; - -for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).substr(1)); -} - -function stringify(arr, offset = 0) { - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields - - if (!(0, _validate.default)(uuid)) { - throw TypeError('Stringified UUID is invalid'); - } - - return uuid; +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); } -var _default = stringify; +var _default = validate; exports["default"] = _default; /***/ }), -/***/ 8628: +/***/ 1595: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -16320,530 +14482,703 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html -let _nodeId; - -let _clockseq; // Previous uuid creation time - - -let _lastMSecs = 0; -let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details - -function v1(options, buf, offset) { - let i = buf && offset || 0; - const b = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || _rng.default)(); - - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } - - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + return parseInt(uuid.substr(14, 1), 16); +} - let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock +var _default = version; +exports["default"] = _default; - let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) +/***/ }), - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression +/***/ 2940: +/***/ ((module) => { - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } // Per 4.2.1.2 Throw error if too many uuids are requested + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + return wrapper - if (nsecs >= 10000) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } +} - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - - msecs += 12219292800000; // `time_low` - - const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; // `time_mid` - - const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; // `time_high_and_version` - - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - - b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` +/***/ }), - b[i++] = clockseq & 0xff; // `node` +/***/ 1547: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } +"use strict"; - return buf || (0, _stringify.default)(b); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const child_process_1 = __nccwpck_require__(2081); +const CONST = __importStar(__nccwpck_require__(4097)); +const sanitizeStringForJSONParse_1 = __importDefault(__nccwpck_require__(9338)); +const VERSION_UPDATER = __importStar(__nccwpck_require__(8007)); +/** + * @param [shallowExcludeTag] When fetching the given tag, exclude all history reachable by the shallowExcludeTag (used to make fetch much faster) + */ +function fetchTag(tag, shallowExcludeTag = '') { + let shouldRetry = true; + let needsRepack = false; + while (shouldRetry) { + try { + let command = ''; + if (needsRepack) { + // We have seen some scenarios where this fixes the git fetch. + // Why? Who knows... https://github.com/Expensify/App/pull/31459 + command = 'git repack -d'; + console.log(`Running command: ${command}`); + (0, child_process_1.execSync)(command); + } + command = `git fetch origin tag ${tag} --no-tags`; + // Note that this condition is only ever NOT true in the 1.0.0-0 edge case + if (shallowExcludeTag && shallowExcludeTag !== tag) { + command += ` --shallow-exclude=${shallowExcludeTag}`; + } + console.log(`Running command: ${command}`); + (0, child_process_1.execSync)(command); + shouldRetry = false; + } + catch (e) { + console.error(e); + if (!needsRepack) { + console.log('Attempting to repack and retry...'); + needsRepack = true; + } + else { + console.error("Repack didn't help, giving up..."); + shouldRetry = false; + } + } + } +} +/** + * Get merge logs between two tags (inclusive) as a JavaScript object. + */ +function getCommitHistoryAsJSON(fromTag, toTag) { + // Fetch tags, exclude commits reachable from the previous patch version (i.e: previous checklist), so that we don't have to fetch the full history + const previousPatchVersion = VERSION_UPDATER.getPreviousVersion(fromTag, VERSION_UPDATER.SEMANTIC_VERSION_LEVELS.PATCH); + fetchTag(fromTag, previousPatchVersion); + fetchTag(toTag, previousPatchVersion); + console.log('Getting pull requests merged between the following tags:', fromTag, toTag); + return new Promise((resolve, reject) => { + let stdout = ''; + let stderr = ''; + const args = ['log', '--format={"commit": "%H", "authorName": "%an", "subject": "%s"},', `${fromTag}...${toTag}`]; + console.log(`Running command: git ${args.join(' ')}`); + const spawnedProcess = (0, child_process_1.spawn)('git', args); + spawnedProcess.on('message', console.log); + spawnedProcess.stdout.on('data', (chunk) => { + console.log(chunk.toString()); + stdout += chunk.toString(); + }); + spawnedProcess.stderr.on('data', (chunk) => { + console.error(chunk.toString()); + stderr += chunk.toString(); + }); + spawnedProcess.on('close', (code) => { + if (code !== 0) { + return reject(new Error(`${stderr}`)); + } + resolve(stdout); + }); + spawnedProcess.on('error', (err) => reject(err)); + }).then((stdout) => { + // Sanitize just the text within commit subjects as that's the only potentially un-parseable text. + const sanitizedOutput = stdout.replace(/(?<="subject": ").*?(?="})/g, (subject) => (0, sanitizeStringForJSONParse_1.default)(subject)); + // Then remove newlines, format as JSON and convert to a proper JS object + const json = `[${sanitizedOutput}]`.replace(/(\r\n|\n|\r)/gm, '').replace('},]', '}]'); + return JSON.parse(json); + }); } +/** + * Parse merged PRs, excluding those from irrelevant branches. + */ +function getValidMergedPRs(commits) { + const mergedPRs = new Set(); + commits.forEach((commit) => { + const author = commit.authorName; + if (author === CONST.OS_BOTIFY) { + return; + } + const match = commit.subject.match(/Merge pull request #(\d+) from (?!Expensify\/.*-cherry-pick-staging)/); + if (!Array.isArray(match) || match.length < 2) { + return; + } + const pr = Number.parseInt(match[1], 10); + if (mergedPRs.has(pr)) { + // If a PR shows up in the log twice, that means that the PR was deployed in the previous checklist. + // That also means that we don't want to include it in the current checklist, so we remove it now. + mergedPRs.delete(pr); + return; + } + mergedPRs.add(pr); + }); + return Array.from(mergedPRs); +} +/** + * Takes in two git tags and returns a list of PR numbers of all PRs merged between those two tags + */ +async function getPullRequestsMergedBetween(fromTag, toTag) { + console.log(`Looking for commits made between ${fromTag} and ${toTag}...`); + const commitList = await getCommitHistoryAsJSON(fromTag, toTag); + console.log(`Commits made between ${fromTag} and ${toTag}:`, commitList); + // Find which commit messages correspond to merged PR's + const pullRequestNumbers = getValidMergedPRs(commitList).sort((a, b) => a - b); + console.log(`List of pull requests merged between ${fromTag} and ${toTag}`, pullRequestNumbers); + return pullRequestNumbers; +} +exports["default"] = { + getValidMergedPRs, + getPullRequestsMergedBetween, +}; -var _default = v1; -exports["default"] = _default; - -/***/ }), - -/***/ 6409: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _md = _interopRequireDefault(__nccwpck_require__(4569)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v3 = (0, _v.default)('v3', 0x30, _md.default); -var _default = v3; -exports["default"] = _default; /***/ }), -/***/ 5998: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; })); -exports["default"] = _default; -exports.URL = exports.DNS = void 0; - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape - - const bytes = []; - - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); - } - - return bytes; -} - -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; - -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); + } + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); + } + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); + } + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); -} - -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; - -/***/ }), - -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; /***/ }), -/***/ 1547: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -const child_process_1 = __nccwpck_require__(2081); -const CONST = __importStar(__nccwpck_require__(4097)); -const sanitizeStringForJSONParse_1 = __importDefault(__nccwpck_require__(9338)); -const VERSION_UPDATER = __importStar(__nccwpck_require__(8007)); -/** - * @param [shallowExcludeTag] When fetching the given tag, exclude all history reachable by the shallowExcludeTag (used to make fetch much faster) - */ -function fetchTag(tag, shallowExcludeTag = '') { - let shouldRetry = true; - let needsRepack = false; - while (shouldRetry) { - try { - let command = ''; - if (needsRepack) { - // We have seen some scenarios where this fixes the git fetch. - // Why? Who knows... https://github.com/Expensify/App/pull/31459 - command = 'git repack -d'; - console.log(`Running command: ${command}`); - (0, child_process_1.execSync)(command); - } - command = `git fetch origin tag ${tag} --no-tags`; - // Note that this condition is only ever NOT true in the 1.0.0-0 edge case - if (shallowExcludeTag && shallowExcludeTag !== tag) { - command += ` --shallow-exclude=${shallowExcludeTag}`; - } - console.log(`Running command: ${command}`); - (0, child_process_1.execSync)(command); - shouldRetry = false; - } - catch (e) { - console.error(e); - if (!needsRepack) { - console.log('Attempting to repack and retry...'); - needsRepack = true; - } - else { - console.error("Repack didn't help, giving up..."); - shouldRetry = false; - } - } - } -} -/** - * Get merge logs between two tags (inclusive) as a JavaScript object. - */ -function getCommitHistoryAsJSON(fromTag, toTag) { - // Fetch tags, exclude commits reachable from the previous patch version (i.e: previous checklist), so that we don't have to fetch the full history - const previousPatchVersion = VERSION_UPDATER.getPreviousVersion(fromTag, VERSION_UPDATER.SEMANTIC_VERSION_LEVELS.PATCH); - fetchTag(fromTag, previousPatchVersion); - fetchTag(toTag, previousPatchVersion); - console.log('Getting pull requests merged between the following tags:', fromTag, toTag); - return new Promise((resolve, reject) => { - let stdout = ''; - let stderr = ''; - const args = ['log', '--format={"commit": "%H", "authorName": "%an", "subject": "%s"},', `${fromTag}...${toTag}`]; - console.log(`Running command: git ${args.join(' ')}`); - const spawnedProcess = (0, child_process_1.spawn)('git', args); - spawnedProcess.on('message', console.log); - spawnedProcess.stdout.on('data', (chunk) => { - console.log(chunk.toString()); - stdout += chunk.toString(); - }); - spawnedProcess.stderr.on('data', (chunk) => { - console.error(chunk.toString()); - stderr += chunk.toString(); - }); - spawnedProcess.on('close', (code) => { - if (code !== 0) { - return reject(new Error(`${stderr}`)); - } - resolve(stdout); - }); - spawnedProcess.on('error', (err) => reject(err)); - }).then((stdout) => { - // Sanitize just the text within commit subjects as that's the only potentially un-parseable text. - const sanitizedOutput = stdout.replace(/(?<="subject": ").*?(?="})/g, (subject) => (0, sanitizeStringForJSONParse_1.default)(subject)); - // Then remove newlines, format as JSON and convert to a proper JS object - const json = `[${sanitizedOutput}]`.replace(/(\r\n|\n|\r)/gm, '').replace('},]', '}]'); - return JSON.parse(json); - }); -} -/** - * Parse merged PRs, excluding those from irrelevant branches. - */ -function getValidMergedPRs(commits) { - const mergedPRs = new Set(); - commits.forEach((commit) => { - const author = commit.authorName; - if (author === CONST.OS_BOTIFY) { - return; - } - const match = commit.subject.match(/Merge pull request #(\d+) from (?!Expensify\/.*-cherry-pick-staging)/); - if (!Array.isArray(match) || match.length < 2) { - return; - } - const pr = Number.parseInt(match[1], 10); - if (mergedPRs.has(pr)) { - // If a PR shows up in the log twice, that means that the PR was deployed in the previous checklist. - // That also means that we don't want to include it in the current checklist, so we remove it now. - mergedPRs.delete(pr); - return; - } - mergedPRs.add(pr); - }); - return Array.from(mergedPRs); -} /** - * Takes in two git tags and returns a list of PR numbers of all PRs merged between those two tags + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. */ -async function getPullRequestsMergedBetween(fromTag, toTag) { - console.log(`Looking for commits made between ${fromTag} and ${toTag}...`); - const commitList = await getCommitHistoryAsJSON(fromTag, toTag); - console.log(`Commits made between ${fromTag} and ${toTag}:`, commitList); - // Find which commit messages correspond to merged PR's - const pullRequestNumbers = getValidMergedPRs(commitList).sort((a, b) => a - b); - console.log(`List of pull requests merged between ${fromTag} and ${toTag}`, pullRequestNumbers); - return pullRequestNumbers; +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } -exports["default"] = { - getValidMergedPRs, - getPullRequestsMergedBetween, -}; +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/getArtifactInfo/index.js b/.github/actions/javascript/getArtifactInfo/index.js index ea56ff5f4ebd..11adfd8bf842 100644 --- a/.github/actions/javascript/getArtifactInfo/index.js +++ b/.github/actions/javascript/getArtifactInfo/index.js @@ -9,7 +9,7 @@ const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); const run = function () { const artifactName = core.getInput('ARTIFACT_NAME', {required: true}); @@ -66,784 +66,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4814,3919 +4268,2309 @@ const Endpoints = { }], renameBranch: ["POST /repos/{owner}/{repo}/branches/{branch}/rename"], replaceAllTopics: ["PUT /repos/{owner}/{repo}/topics"], - requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], - setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], - setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { - mapToData: "apps" - }], - setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { - mapToData: "contexts" - }], - setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { - mapToData: "teams" - }], - setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { - mapToData: "users" - }], - testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], - transfer: ["POST /repos/{owner}/{repo}/transfer"], - update: ["PATCH /repos/{owner}/{repo}"], - updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], - updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], - updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], - updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], - updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], + setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], + transfer: ["POST /repos/{owner}/{repo}/transfer"], + update: ["PATCH /repos/{owner}/{repo}"], + updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], + updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], + updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], + updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; + +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +"use strict"; -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = Hash; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; -module.exports = ListCache; + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ }), + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + const req = state.global.key(state.id).schedule(jobOptions, request, options); -module.exports = Map; + if (isGraphQL) { + const res = await req; + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -/***/ }), + return req; +} -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +function routeMatcher(paths) { + // EXAMPLE. For the following paths: -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -module.exports = MapCache; + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ + return new RegExp(regex, "i"); +} -/***/ }), +// @ts-expect-error -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -var root = __nccwpck_require__(9882); +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -/** Built-in value references. */ -var Symbol = root.Symbol; +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -module.exports = Symbol; + if (!enabled) { + return {}; + } + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 4356: -/***/ ((module) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling - while (++index < length) { - result[index] = iteratee(array[index], index, array); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); } - return result; -} -module.exports = arrayMap; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -/***/ }), + events.on("rate-limit", state.onRateLimit); // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -var eq = __nccwpck_require__(1901); + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } + + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + return {}; + }(); + + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; } - } - return -1; + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = assocIndexOf; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5758: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) - var index = 0, - length = path.length; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) } -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +function HookCollection () { + var state = { + registry: {} + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return hook +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return HookCollection() } -module.exports = baseIsNative; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +/***/ 5549: +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +module.exports = addHook; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} -module.exports = baseToString; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4670: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = register; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!options) { + options = {}; + } -var root = __nccwpck_require__(9882); + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -module.exports = coreJsData; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} /***/ }), -/***/ 2085: +/***/ 6819: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - +module.exports = removeHook; -/***/ }), +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + if (index === -1) { + return; + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + state.registry[name].splice(index, 1); } -module.exports = getNative; - /***/ }), -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13411,230 +11255,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/getDeployPullRequestList/index.js b/.github/actions/javascript/getDeployPullRequestList/index.js index f272929d536a..30cef0dbdc68 100644 --- a/.github/actions/javascript/getDeployPullRequestList/index.js +++ b/.github/actions/javascript/getDeployPullRequestList/index.js @@ -12,7 +12,7 @@ const core = __nccwpck_require__(2186); const github = __nccwpck_require__(5438); const ActionUtils = __nccwpck_require__(970); const GitUtils = (__nccwpck_require__(1547)["default"]); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); async function run() { try { @@ -122,740 +122,637 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9338: +/***/ ((module) => { + +const replacer = (str) => + ({ + '\\': '\\\\', + '\t': '\\t', + '\n': '\\n', + '\r': '\\r', + '\f': '\\f', + '"': '\\"', + }[str]); + +/** + * Replace any characters in the string that will break JSON.parse for our Git Log output + * + * Solution partly taken from SO user Gabriel Rodríguez Flores 🙇 + * https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading + * + * @param {String} inputString + * @returns {String} + */ +module.exports = function (inputString) { + if (typeof inputString !== 'string') { + throw new TypeError('Input must me of type String'); + } + + // Replace any newlines and escape backslashes + return inputString.replace(/\\|\t|\n|\r|\f|"/g, replacer); +}; + +/***/ }), + +/***/ 8007: +/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { + +"use strict"; +__nccwpck_require__.r(__webpack_exports__); +/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { +/* harmony export */ "MAX_INCREMENTS": () => (/* binding */ MAX_INCREMENTS), +/* harmony export */ "SEMANTIC_VERSION_LEVELS": () => (/* binding */ SEMANTIC_VERSION_LEVELS), +/* harmony export */ "getPreviousVersion": () => (/* binding */ getPreviousVersion), +/* harmony export */ "getVersionNumberFromString": () => (/* binding */ getVersionNumberFromString), +/* harmony export */ "getVersionStringFromNumber": () => (/* binding */ getVersionStringFromNumber), +/* harmony export */ "incrementMinor": () => (/* binding */ incrementMinor), +/* harmony export */ "incrementPatch": () => (/* binding */ incrementPatch), +/* harmony export */ "incrementVersion": () => (/* binding */ incrementVersion) +/* harmony export */ }); const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +const SEMANTIC_VERSION_LEVELS = { + MAJOR: 'MAJOR', + MINOR: 'MINOR', + PATCH: 'PATCH', + BUILD: 'BUILD', +}; +const MAX_INCREMENTS = 99; /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Transforms a versions string into a number + * + * @param {String} versionString + * @returns {Array} */ -const POLL_RATE = 10000; +const getVersionNumberFromString = (versionString) => { + const [version, build] = versionString.split('-'); + const [major, minor, patch] = _.map(version.split('.'), (n) => Number(n)); -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); + return [major, minor, patch, Number.isInteger(Number(build)) ? Number(build) : 0]; +}; - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } +/** + * Transforms version numbers components into a version string + * + * @param {Number} major + * @param {Number} minor + * @param {Number} patch + * @param {Number} [build] + * @returns {String} + */ +const getVersionStringFromNumber = (major, minor, patch, build = 0) => `${major}.${minor}.${patch}-${build}`; - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; +/** + * Increments a minor version + * + * @param {Number} major + * @param {Number} minor + * @returns {String} + */ +const incrementMinor = (major, minor) => { + if (minor < MAX_INCREMENTS) { + return getVersionStringFromNumber(major, minor + 1, 0, 0); } - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; - } - this.initOctokit(); - return this.internalOctokit.graphql; - } + return getVersionStringFromNumber(major + 1, 0, 0, 0); +}; - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; - } - this.initOctokit(); - return this.internalOctokit.paginate; +/** + * Increments a Patch version + * + * @param {Number} major + * @param {Number} minor + * @param {Number} patch + * @returns {String} + */ +const incrementPatch = (major, minor, patch) => { + if (patch < MAX_INCREMENTS) { + return getVersionStringFromNumber(major, minor, patch + 1, 0); } + return incrementMinor(major, minor); +}; - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/** + * Increments a build version + * + * @param {String} version + * @param {String} level + * @returns {String} + */ +const incrementVersion = (version, level) => { + const [major, minor, patch, build] = getVersionNumberFromString(version); - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } + // Majors will always be incremented + if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { + return getVersionStringFromNumber(major + 1, 0, 0, 0); + } - return this.getStagingDeployCashData(data[0]); - }); + if (level === SEMANTIC_VERSION_LEVELS.MINOR) { + return incrementMinor(major, minor); } - /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} - */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } + if (level === SEMANTIC_VERSION_LEVELS.PATCH) { + return incrementPatch(major, minor, patch); } - /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] - */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + if (build < MAX_INCREMENTS) { + return getVersionStringFromNumber(major, minor, patch, build + 1); } - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; + return incrementPatch(major, minor, patch); +}; + +/** + * @param {String} currentVersion + * @param {String} level + * @returns {String} + */ +function getPreviousVersion(currentVersion, level) { + const [major, minor, patch, build] = getVersionNumberFromString(currentVersion); + + if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { + if (major === 1) { + return getVersionStringFromNumber(1, 0, 0, 0); } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); + return getVersionStringFromNumber(major - 1, 0, 0, 0); } - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; + if (level === SEMANTIC_VERSION_LEVELS.MINOR) { + if (minor === 0) { + return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MAJOR); } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); + return getVersionStringFromNumber(major, minor - 1, 0, 0); } - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); + if (level === SEMANTIC_VERSION_LEVELS.PATCH) { + if (patch === 0) { + return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MINOR); + } + return getVersionStringFromNumber(major, minor, patch - 1, 0); + } - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); + if (build === 0) { + return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.PATCH); + } + return getVersionStringFromNumber(major, minor, patch, build - 1); +} - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } +/***/ }), - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; +"use strict"; - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } +/***/ }), - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} + * A code indicating that the action was successful */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} + * A code indicating that the action was a failure */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + else { + command_1.issueCommand('add-path', {}, inputPath); } + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; } - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 9338: -/***/ ((module) => { - -const replacer = (str) => - ({ - '\\': '\\\\', - '\t': '\\t', - '\n': '\\n', - '\r': '\\r', - '\f': '\\f', - '"': '\\"', - }[str]); - +exports.addPath = addPath; /** - * Replace any characters in the string that will break JSON.parse for our Git Log output - * - * Solution partly taken from SO user Gabriel Rodríguez Flores 🙇 - * https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. * - * @param {String} inputString - * @returns {String} + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string */ -module.exports = function (inputString) { - if (typeof inputString !== 'string') { - throw new TypeError('Input must me of type String'); +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - // Replace any newlines and escape backslashes - return inputString.replace(/\\|\t|\n|\r|\f|"/g, replacer); -}; - - -/***/ }), - -/***/ 8007: -/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { - -"use strict"; -__nccwpck_require__.r(__webpack_exports__); -/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { -/* harmony export */ "MAX_INCREMENTS": () => (/* binding */ MAX_INCREMENTS), -/* harmony export */ "SEMANTIC_VERSION_LEVELS": () => (/* binding */ SEMANTIC_VERSION_LEVELS), -/* harmony export */ "getPreviousVersion": () => (/* binding */ getPreviousVersion), -/* harmony export */ "getVersionNumberFromString": () => (/* binding */ getVersionNumberFromString), -/* harmony export */ "getVersionStringFromNumber": () => (/* binding */ getVersionStringFromNumber), -/* harmony export */ "incrementMinor": () => (/* binding */ incrementMinor), -/* harmony export */ "incrementPatch": () => (/* binding */ incrementPatch), -/* harmony export */ "incrementVersion": () => (/* binding */ incrementVersion) -/* harmony export */ }); -const _ = __nccwpck_require__(5067); - -const SEMANTIC_VERSION_LEVELS = { - MAJOR: 'MAJOR', - MINOR: 'MINOR', - PATCH: 'PATCH', - BUILD: 'BUILD', -}; -const MAX_INCREMENTS = 99; - + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); +} +exports.getInput = getInput; /** - * Transforms a versions string into a number + * Gets the values of an multiline input. Each value is also trimmed. * - * @param {String} versionString - * @returns {Array} - */ -const getVersionNumberFromString = (versionString) => { - const [version, build] = versionString.split('-'); - const [major, minor, patch] = _.map(version.split('.'), (n) => Number(n)); - - return [major, minor, patch, Number.isInteger(Number(build)) ? Number(build) : 0]; -}; - -/** - * Transforms version numbers components into a version string + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] * - * @param {Number} major - * @param {Number} minor - * @param {Number} patch - * @param {Number} [build] - * @returns {String} */ -const getVersionStringFromNumber = (major, minor, patch, build = 0) => `${major}.${minor}.${patch}-${build}`; - +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; /** - * Increments a minor version + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 * - * @param {Number} major - * @param {Number} minor - * @returns {String} + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean */ -const incrementMinor = (major, minor) => { - if (minor < MAX_INCREMENTS) { - return getVersionStringFromNumber(major, minor + 1, 0, 0); - } - - return getVersionStringFromNumber(major + 1, 0, 0, 0); -}; - +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; /** - * Increments a Patch version + * Sets the value of an output. * - * @param {Number} major - * @param {Number} minor - * @param {Number} patch - * @returns {String} + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify */ -const incrementPatch = (major, minor, patch) => { - if (patch < MAX_INCREMENTS) { - return getVersionStringFromNumber(major, minor, patch + 1, 0); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); } - return incrementMinor(major, minor); -}; - + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; /** - * Increments a build version + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. * - * @param {String} version - * @param {String} level - * @returns {String} */ -const incrementVersion = (version, level) => { - const [major, minor, patch, build] = getVersionNumberFromString(version); - - // Majors will always be incremented - if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { - return getVersionStringFromNumber(major + 1, 0, 0, 0); - } - - if (level === SEMANTIC_VERSION_LEVELS.MINOR) { - return incrementMinor(major, minor); - } - - if (level === SEMANTIC_VERSION_LEVELS.PATCH) { - return incrementPatch(major, minor, patch); - } - - if (build < MAX_INCREMENTS) { - return getVersionStringFromNumber(major, minor, patch, build + 1); - } - - return incrementPatch(major, minor, patch); -}; - +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- /** - * @param {String} currentVersion - * @param {String} level - * @returns {String} + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message */ -function getPreviousVersion(currentVersion, level) { - const [major, minor, patch, build] = getVersionNumberFromString(currentVersion); - - if (level === SEMANTIC_VERSION_LEVELS.MAJOR) { - if (major === 1) { - return getVersionStringFromNumber(1, 0, 0, 0); - } - return getVersionStringFromNumber(major - 1, 0, 0, 0); - } - - if (level === SEMANTIC_VERSION_LEVELS.MINOR) { - if (minor === 0) { - return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MAJOR); +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); } - return getVersionStringFromNumber(major, minor - 1, 0, 0); - } - - if (level === SEMANTIC_VERSION_LEVELS.PATCH) { - if (patch === 0) { - return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.MINOR); + finally { + endGroup(); } - return getVersionStringFromNumber(major, minor, patch - 1, 0); - } - - if (build === 0) { - return getPreviousVersion(currentVersion, SEMANTIC_VERSION_LEVELS.PATCH); + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); } - return getVersionStringFromNumber(major, minor, patch, build - 1); + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); } - - - +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map /***/ }), -/***/ 7351: +/***/ 717: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +// For internal use, subject to change. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -876,81 +773,130 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); const os = __importStar(__nccwpck_require__(2037)); +const uuid_1 = __nccwpck_require__(5840); const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); } -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; } -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.result.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } } -//# sourceMappingURL=command.js.map +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map /***/ }), -/***/ 2186: +/***/ 2981: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -974,6 +920,52 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -984,465 +976,390 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } /** - * A code indicating that the action was successful + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path */ - ExitCode[ExitCode["Success"] = 0] = "Success"; + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } /** - * A code indicating that the action was a failure + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; } - else { - command_1.issueCommand('add-path', {}, inputPath); + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); } - if (options && options.trimWhitespace === false) { - return val; + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; } - return inputs.map(input => input.trim()); -} -exports.getMultilineInput = getMultilineInput; -/** - * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. - * Support boolean input list: `true | True | TRUE | false | False | FALSE` . - * The return value is also in boolean type. - * ref: https://yaml.org/spec/1.2/spec.html#id2804923 - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns boolean - */ -function getBooleanInput(name, options) { - const trueValue = ['true', 'True', 'TRUE']; - const falseValue = ['false', 'False', 'FALSE']; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + - `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); -} -exports.getBooleanInput = getBooleanInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - const filePath = process.env['GITHUB_OUTPUT'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; } - process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. - * - */ -function setCommandEcho(enabled) { - command_1.issue('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function error(message, properties = {}) { - command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.error = error; -/** - * Adds a warning issue - * @param message warning issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function warning(message, properties = {}) { - command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.warning = warning; -/** - * Adds a notice issue - * @param message notice issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function notice(message, properties = {}) { - command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.notice = notice; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); -} -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - command_1.issue('group', name); -} -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - command_1.issue('endgroup'); -} -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); -} -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function saveState(name, value) { - const filePath = process.env['GITHUB_STATE'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; + } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); } - command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); -} -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; -} -exports.getState = getState; -function getIDToken(aud) { - return __awaiter(this, void 0, void 0, function* () { - return yield oidc_utils_1.OidcClient.getIDToken(aud); - }); } -exports.getIDToken = getIDToken; -/** - * Summary exports - */ -var summary_1 = __nccwpck_require__(1327); -Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); -/** - * @deprecated use core.summary - */ -var summary_2 = __nccwpck_require__(1327); -Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +const _summary = new Summary(); /** - * Path exports + * @deprecated use `core.summary` */ -var path_utils_1 = __nccwpck_require__(2981); -Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); -Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); -Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); -//# sourceMappingURL=core.js.map +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map /***/ }), -/***/ 717: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 5278: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -// For internal use, subject to change. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ -const fs = __importStar(__nccwpck_require__(7147)); -const os = __importStar(__nccwpck_require__(2037)); -const uuid_1 = __nccwpck_require__(5840); -const utils_1 = __nccwpck_require__(5278); -function issueFileCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; - if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); - } - if (!fs.existsSync(filePath)) { - throw new Error(`Missing file at path: ${filePath}`); - } - fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { - encoding: 'utf8' - }); -} -exports.issueFileCommand = issueFileCommand; -function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - const convertedValue = utils_1.toCommandValue(value); - // These should realistically never happen, but just in case someone finds a - // way to exploit uuid generation let's not allow keys or values that contain - // the delimiter. - if (key.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; } - if (convertedValue.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + else if (typeof input === 'string' || input instanceof String) { + return input; } - return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; + return JSON.stringify(input); } -exports.prepareKeyValueMessage = prepareKeyValueMessage; -//# sourceMappingURL=file-command.js.map +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; + } + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; +} +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 8041: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 4087: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.OidcClient = void 0; -const http_client_1 = __nccwpck_require__(6255); -const auth_1 = __nccwpck_require__(5526); -const core_1 = __nccwpck_require__(2186); -class OidcClient { - static createHttpClient(allowRetry = true, maxRetry = 10) { - const requestOptions = { - allowRetries: allowRetry, - maxRetries: maxRetry - }; - return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); - } - static getRequestToken() { - const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; - if (!token) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); - } - return token; - } - static getIDTokenUrl() { - const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; - if (!runtimeUrl) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); +exports.Context = void 0; +const fs_1 = __nccwpck_require__(7147); +const os_1 = __nccwpck_require__(2037); +class Context { + /** + * Hydrate the context from the environment + */ + constructor() { + var _a, _b, _c; + this.payload = {}; + if (process.env.GITHUB_EVENT_PATH) { + if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { + this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); + } + else { + const path = process.env.GITHUB_EVENT_PATH; + process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); + } } - return runtimeUrl; + this.eventName = process.env.GITHUB_EVENT_NAME; + this.sha = process.env.GITHUB_SHA; + this.ref = process.env.GITHUB_REF; + this.workflow = process.env.GITHUB_WORKFLOW; + this.action = process.env.GITHUB_ACTION; + this.actor = process.env.GITHUB_ACTOR; + this.job = process.env.GITHUB_JOB; + this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); + this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); + this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; + this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; + this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; } - static getCall(id_token_url) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const httpclient = OidcClient.createHttpClient(); - const res = yield httpclient - .getJson(id_token_url) - .catch(error => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n - Error Message: ${error.result.message}`); - }); - const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; - if (!id_token) { - throw new Error('Response json body do not have ID Token field'); - } - return id_token; - }); + get issue() { + const payload = this.payload; + return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); } - static getIDToken(audience) { - return __awaiter(this, void 0, void 0, function* () { - try { - // New ID Token is requested from action service - let id_token_url = OidcClient.getIDTokenUrl(); - if (audience) { - const encodedAudience = encodeURIComponent(audience); - id_token_url = `${id_token_url}&audience=${encodedAudience}`; - } - core_1.debug(`ID token url is ${id_token_url}`); - const id_token = yield OidcClient.getCall(id_token_url); - core_1.setSecret(id_token); - return id_token; - } - catch (error) { - throw new Error(`Error message: ${error.message}`); - } - }); + get repo() { + if (process.env.GITHUB_REPOSITORY) { + const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); + return { owner, repo }; + } + if (this.payload.repository) { + return { + owner: this.payload.repository.owner.login, + repo: this.payload.repository.name + }; + } + throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); } } -exports.OidcClient = OidcClient; -//# sourceMappingURL=oidc-utils.js.map +exports.Context = Context; +//# sourceMappingURL=context.js.map /***/ }), -/***/ 2981: +/***/ 5438: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -1467,1245 +1384,1121 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; -const path = __importStar(__nccwpck_require__(1017)); -/** - * toPosixPath converts the given path to the posix form. On Windows, \\ will be - * replaced with /. - * - * @param pth. Path to transform. - * @return string Posix path. - */ -function toPosixPath(pth) { - return pth.replace(/[\\]/g, '/'); -} -exports.toPosixPath = toPosixPath; -/** - * toWin32Path converts the given path to the win32 form. On Linux, / will be - * replaced with \\. - * - * @param pth. Path to transform. - * @return string Win32 path. - */ -function toWin32Path(pth) { - return pth.replace(/[/]/g, '\\'); -} -exports.toWin32Path = toWin32Path; +exports.getOctokit = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const utils_1 = __nccwpck_require__(3030); +exports.context = new Context.Context(); /** - * toPlatformPath converts the given path to a platform-specific path. It does - * this by replacing instances of / and \ with the platform-specific path - * separator. + * Returns a hydrated octokit ready to use for GitHub Actions * - * @param pth The path to platformize. - * @return string The platform-specific path. + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set */ -function toPlatformPath(pth) { - return pth.replace(/[/\\]/g, path.sep); +function getOctokit(token, options, ...additionalPlugins) { + const GitHubWithPlugins = utils_1.GitHub.plugin(...additionalPlugins); + return new GitHubWithPlugins(utils_1.getOctokitOptions(token, options)); } -exports.toPlatformPath = toPlatformPath; -//# sourceMappingURL=path-utils.js.map +exports.getOctokit = getOctokit; +//# sourceMappingURL=github.js.map /***/ }), -/***/ 1327: +/***/ 7914: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; -const os_1 = __nccwpck_require__(2037); -const fs_1 = __nccwpck_require__(7147); -const { access, appendFile, writeFile } = fs_1.promises; -exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; -exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; -class Summary { - constructor() { - this._buffer = ''; +exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; +const httpClient = __importStar(__nccwpck_require__(6255)); +function getAuthString(token, options) { + if (!token && !options.auth) { + throw new Error('Parameter token or opts.auth is required'); } - /** - * Finds the summary file path from the environment, rejects if env var is not found or file does not exist - * Also checks r/w permissions. - * - * @returns step summary file path - */ - filePath() { - return __awaiter(this, void 0, void 0, function* () { - if (this._filePath) { - return this._filePath; - } - const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; - if (!pathFromEnv) { - throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); - } - try { - yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); - } - catch (_a) { - throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); - } - this._filePath = pathFromEnv; - return this._filePath; - }); + else if (token && options.auth) { + throw new Error('Parameters token and opts.auth may not both be specified'); } - /** - * Wraps content in an HTML tag, adding any HTML attributes - * - * @param {string} tag HTML tag to wrap - * @param {string | null} content content within the tag - * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add - * - * @returns {string} content wrapped in HTML element - */ - wrap(tag, content, attrs = {}) { - const htmlAttrs = Object.entries(attrs) - .map(([key, value]) => ` ${key}="${value}"`) - .join(''); - if (!content) { - return `<${tag}${htmlAttrs}>`; - } - return `<${tag}${htmlAttrs}>${content}`; + return typeof options.auth === 'string' ? options.auth : `token ${token}`; +} +exports.getAuthString = getAuthString; +function getProxyAgent(destinationUrl) { + const hc = new httpClient.HttpClient(); + return hc.getAgent(destinationUrl); +} +exports.getProxyAgent = getProxyAgent; +function getApiBaseUrl() { + return process.env['GITHUB_API_URL'] || 'https://api.github.com'; +} +exports.getApiBaseUrl = getApiBaseUrl; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 3030: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const Utils = __importStar(__nccwpck_require__(7914)); +// octokit + plugins +const core_1 = __nccwpck_require__(8525); +const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); +const plugin_paginate_rest_1 = __nccwpck_require__(8945); +exports.context = new Context.Context(); +const baseUrl = Utils.getApiBaseUrl(); +exports.defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) } - /** - * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. - * - * @param {SummaryWriteOptions} [options] (optional) options for write operation - * - * @returns {Promise} summary instance - */ - write(options) { - return __awaiter(this, void 0, void 0, function* () { - const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); - const filePath = yield this.filePath(); - const writeFunc = overwrite ? writeFile : appendFile; - yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); - return this.emptyBuffer(); - }); +}; +exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); +/** + * Convience function to correctly format Octokit Options to pass into the constructor. + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +function getOctokitOptions(token, options) { + const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller + // Auth + const auth = Utils.getAuthString(token, opts); + if (auth) { + opts.auth = auth; } - /** - * Clears the summary buffer and wipes the summary file - * - * @returns {Summary} summary instance - */ - clear() { - return __awaiter(this, void 0, void 0, function* () { - return this.emptyBuffer().write({ overwrite: true }); - }); - } - /** - * Returns the current summary buffer as a string - * - * @returns {string} string of summary buffer - */ - stringify() { - return this._buffer; - } - /** - * If the summary buffer is empty - * - * @returns {boolen} true if the buffer is empty - */ - isEmptyBuffer() { - return this._buffer.length === 0; - } - /** - * Resets the summary buffer without writing to summary file - * - * @returns {Summary} summary instance - */ - emptyBuffer() { - this._buffer = ''; - return this; - } - /** - * Adds raw text to the summary buffer - * - * @param {string} text content to add - * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) - * - * @returns {Summary} summary instance - */ - addRaw(text, addEOL = false) { - this._buffer += text; - return addEOL ? this.addEOL() : this; - } - /** - * Adds the operating system-specific end-of-line marker to the buffer - * - * @returns {Summary} summary instance - */ - addEOL() { - return this.addRaw(os_1.EOL); - } - /** - * Adds an HTML codeblock to the summary buffer - * - * @param {string} code content to render within fenced code block - * @param {string} lang (optional) language to syntax highlight code - * - * @returns {Summary} summary instance - */ - addCodeBlock(code, lang) { - const attrs = Object.assign({}, (lang && { lang })); - const element = this.wrap('pre', this.wrap('code', code), attrs); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML list to the summary buffer - * - * @param {string[]} items list of items to render - * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) - * - * @returns {Summary} summary instance - */ - addList(items, ordered = false) { - const tag = ordered ? 'ol' : 'ul'; - const listItems = items.map(item => this.wrap('li', item)).join(''); - const element = this.wrap(tag, listItems); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML table to the summary buffer - * - * @param {SummaryTableCell[]} rows table rows - * - * @returns {Summary} summary instance - */ - addTable(rows) { - const tableBody = rows - .map(row => { - const cells = row - .map(cell => { - if (typeof cell === 'string') { - return this.wrap('td', cell); - } - const { header, data, colspan, rowspan } = cell; - const tag = header ? 'th' : 'td'; - const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); - return this.wrap(tag, data, attrs); - }) - .join(''); - return this.wrap('tr', cells); - }) - .join(''); - const element = this.wrap('table', tableBody); - return this.addRaw(element).addEOL(); - } - /** - * Adds a collapsable HTML details element to the summary buffer - * - * @param {string} label text for the closed state - * @param {string} content collapsable content - * - * @returns {Summary} summary instance - */ - addDetails(label, content) { - const element = this.wrap('details', this.wrap('summary', label) + content); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML image tag to the summary buffer - * - * @param {string} src path to the image you to embed - * @param {string} alt text description of the image - * @param {SummaryImageOptions} options (optional) addition image attributes - * - * @returns {Summary} summary instance - */ - addImage(src, alt, options) { - const { width, height } = options || {}; - const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); - const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML section heading element - * - * @param {string} text heading text - * @param {number | string} [level=1] (optional) the heading level, default: 1 - * - * @returns {Summary} summary instance - */ - addHeading(text, level) { - const tag = `h${level}`; - const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) - ? tag - : 'h1'; - const element = this.wrap(allowedTag, text); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML thematic break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addSeparator() { - const element = this.wrap('hr', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML line break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addBreak() { - const element = this.wrap('br', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML blockquote to the summary buffer - * - * @param {string} text quote text - * @param {string} cite (optional) citation url - * - * @returns {Summary} summary instance - */ - addQuote(text, cite) { - const attrs = Object.assign({}, (cite && { cite })); - const element = this.wrap('blockquote', text, attrs); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML anchor tag to the summary buffer - * - * @param {string} text link text/content - * @param {string} href hyperlink - * - * @returns {Summary} summary instance - */ - addLink(text, href) { - const element = this.wrap('a', text, { href }); - return this.addRaw(element).addEOL(); + return opts; +} +exports.getOctokitOptions = getOctokitOptions; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 673: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; +const REGEX_IS_INSTALLATION = /^ghs_/; +const REGEX_IS_USER_TO_SERVER = /^ghu_/; +async function auth(token) { + const isApp = token.split(/\./).length === 3; + const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); + const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); + const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; + return { + type: "token", + token: token, + tokenType + }; +} + +/** + * Prefix token for usage in the Authorization header + * + * @param token OAuth token or JSON Web Token + */ +function withAuthorizationPrefix(token) { + if (token.split(/\./).length === 3) { + return `bearer ${token}`; + } + + return `token ${token}`; +} + +async function hook(token, request, route, parameters) { + const endpoint = request.endpoint.merge(route, parameters); + endpoint.headers.authorization = withAuthorizationPrefix(token); + return request(endpoint); +} + +const createTokenAuth = function createTokenAuth(token) { + if (!token) { + throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); + } + + if (typeof token !== "string") { + throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); + } + + token = token.replace(/^(token|bearer) +/i, ""); + return Object.assign(auth.bind(null, token), { + hook: hook.bind(null, token) + }); +}; + +exports.createTokenAuth = createTokenAuth; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 8525: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var universalUserAgent = __nccwpck_require__(5030); +var beforeAfterHook = __nccwpck_require__(3682); +var request = __nccwpck_require__(9353); +var graphql = __nccwpck_require__(6422); +var authToken = __nccwpck_require__(673); + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; } + } + + return target; } -const _summary = new Summary(); -/** - * @deprecated use `core.summary` - */ -exports.markdownSummary = _summary; -exports.summary = _summary; -//# sourceMappingURL=summary.js.map -/***/ }), +const VERSION = "3.6.0"; -/***/ 5278: -/***/ ((__unused_webpack_module, exports) => { +const _excluded = ["authStrategy"]; +class Octokit { + constructor(options = {}) { + const hook = new beforeAfterHook.Collection(); + const requestDefaults = { + baseUrl: request.request.endpoint.DEFAULTS.baseUrl, + headers: {}, + request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type + hook: hook.bind(null, "request") + }), + mediaType: { + previews: [], + format: "" + } + }; // prepend default user agent with `options.userAgent` if set -"use strict"; + requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toCommandProperties = exports.toCommandValue = void 0; -/** - * Sanitizes an input into a string so it can be passed into issueCommand safely - * @param input input to sanitize into a string - */ -function toCommandValue(input) { - if (input === null || input === undefined) { - return ''; + if (options.baseUrl) { + requestDefaults.baseUrl = options.baseUrl; } - else if (typeof input === 'string' || input instanceof String) { - return input; + + if (options.previews) { + requestDefaults.mediaType.previews = options.previews; } - return JSON.stringify(input); -} -exports.toCommandValue = toCommandValue; -/** - * - * @param annotationProperties - * @returns The command properties to send with the actual annotation command - * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 - */ -function toCommandProperties(annotationProperties) { - if (!Object.keys(annotationProperties).length) { - return {}; + + if (options.timeZone) { + requestDefaults.headers["time-zone"] = options.timeZone; } - return { - title: annotationProperties.title, - file: annotationProperties.file, - line: annotationProperties.startLine, - endLine: annotationProperties.endLine, - col: annotationProperties.startColumn, - endColumn: annotationProperties.endColumn - }; -} -exports.toCommandProperties = toCommandProperties; -//# sourceMappingURL=utils.js.map -/***/ }), + this.request = request.request.defaults(requestDefaults); + this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); + this.log = Object.assign({ + debug: () => {}, + info: () => {}, + warn: console.warn.bind(console), + error: console.error.bind(console) + }, options.log); + this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance + // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. + // (2) If only `options.auth` is set, use the default token authentication strategy. + // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. + // TODO: type `options.auth` based on `options.authStrategy`. -/***/ 4087: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (!options.authStrategy) { + if (!options.auth) { + // (1) + this.auth = async () => ({ + type: "unauthenticated" + }); + } else { + // (2) + const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ -"use strict"; + hook.wrap("request", auth.hook); + this.auth = auth; + } + } else { + const { + authStrategy + } = options, + otherOptions = _objectWithoutProperties(options, _excluded); -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Context = void 0; -const fs_1 = __nccwpck_require__(7147); -const os_1 = __nccwpck_require__(2037); -class Context { - /** - * Hydrate the context from the environment - */ - constructor() { - var _a, _b, _c; - this.payload = {}; - if (process.env.GITHUB_EVENT_PATH) { - if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { - this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); - } - else { - const path = process.env.GITHUB_EVENT_PATH; - process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); - } - } - this.eventName = process.env.GITHUB_EVENT_NAME; - this.sha = process.env.GITHUB_SHA; - this.ref = process.env.GITHUB_REF; - this.workflow = process.env.GITHUB_WORKFLOW; - this.action = process.env.GITHUB_ACTION; - this.actor = process.env.GITHUB_ACTOR; - this.job = process.env.GITHUB_JOB; - this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); - this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); - this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; - this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; - this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; - } - get issue() { - const payload = this.payload; - return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); - } - get repo() { - if (process.env.GITHUB_REPOSITORY) { - const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); - return { owner, repo }; - } - if (this.payload.repository) { - return { - owner: this.payload.repository.owner.login, - repo: this.payload.repository.name - }; + const auth = authStrategy(Object.assign({ + request: this.request, + log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. + octokit: this, + octokitOptions: otherOptions + }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ + + hook.wrap("request", auth.hook); + this.auth = auth; + } // apply plugins + // https://stackoverflow.com/a/16345172 + + + const classConstructor = this.constructor; + classConstructor.plugins.forEach(plugin => { + Object.assign(this, plugin(this, options)); + }); + } + + static defaults(defaults) { + const OctokitWithDefaults = class extends this { + constructor(...args) { + const options = args[0] || {}; + + if (typeof defaults === "function") { + super(defaults(options)); + return; } - throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); - } -} -exports.Context = Context; -//# sourceMappingURL=context.js.map -/***/ }), + super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { + userAgent: `${options.userAgent} ${defaults.userAgent}` + } : null)); + } -/***/ 5438: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + }; + return OctokitWithDefaults; + } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOctokit = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(4087)); -const utils_1 = __nccwpck_require__(3030); -exports.context = new Context.Context(); -/** - * Returns a hydrated octokit ready to use for GitHub Actions - * - * @param token the repo PAT or GITHUB_TOKEN - * @param options other options to set - */ -function getOctokit(token, options, ...additionalPlugins) { - const GitHubWithPlugins = utils_1.GitHub.plugin(...additionalPlugins); - return new GitHubWithPlugins(utils_1.getOctokitOptions(token, options)); + static plugin(...newPlugins) { + var _a; + + const currentPlugins = this.plugins; + const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); + return NewOctokit; + } + } -exports.getOctokit = getOctokit; -//# sourceMappingURL=github.js.map +Octokit.VERSION = VERSION; +Octokit.plugins = []; + +exports.Octokit = Octokit; +//# sourceMappingURL=index.js.map + /***/ }), -/***/ 7914: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 8713: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; + Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; -const httpClient = __importStar(__nccwpck_require__(6255)); -function getAuthString(token, options) { - if (!token && !options.auth) { - throw new Error('Parameter token or opts.auth is required'); - } - else if (token && options.auth) { - throw new Error('Parameters token and opts.auth may not both be specified'); - } - return typeof options.auth === 'string' ? options.auth : `token ${token}`; -} -exports.getAuthString = getAuthString; -function getProxyAgent(destinationUrl) { - const hc = new httpClient.HttpClient(); - return hc.getAgent(destinationUrl); -} -exports.getProxyAgent = getProxyAgent; -function getApiBaseUrl() { - return process.env['GITHUB_API_URL'] || 'https://api.github.com'; -} -exports.getApiBaseUrl = getApiBaseUrl; -//# sourceMappingURL=utils.js.map -/***/ }), +var isPlainObject = __nccwpck_require__(3287); +var universalUserAgent = __nccwpck_require__(5030); -/***/ 3030: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +function lowercaseKeys(object) { + if (!object) { + return {}; + } -"use strict"; + return Object.keys(object).reduce((newObj, key) => { + newObj[key.toLowerCase()] = object[key]; + return newObj; + }, {}); +} -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(4087)); -const Utils = __importStar(__nccwpck_require__(7914)); -// octokit + plugins -const core_1 = __nccwpck_require__(8525); -const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); -const plugin_paginate_rest_1 = __nccwpck_require__(8945); -exports.context = new Context.Context(); -const baseUrl = Utils.getApiBaseUrl(); -exports.defaults = { - baseUrl, - request: { - agent: Utils.getProxyAgent(baseUrl) - } -}; -exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); -/** - * Convience function to correctly format Octokit Options to pass into the constructor. - * - * @param token the repo PAT or GITHUB_TOKEN - * @param options other options to set - */ -function getOctokitOptions(token, options) { - const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller - // Auth - const auth = Utils.getAuthString(token, opts); - if (auth) { - opts.auth = auth; +function mergeDeep(defaults, options) { + const result = Object.assign({}, defaults); + Object.keys(options).forEach(key => { + if (isPlainObject.isPlainObject(options[key])) { + if (!(key in defaults)) Object.assign(result, { + [key]: options[key] + });else result[key] = mergeDeep(defaults[key], options[key]); + } else { + Object.assign(result, { + [key]: options[key] + }); } - return opts; + }); + return result; } -exports.getOctokitOptions = getOctokitOptions; -//# sourceMappingURL=utils.js.map -/***/ }), +function removeUndefinedProperties(obj) { + for (const key in obj) { + if (obj[key] === undefined) { + delete obj[key]; + } + } -/***/ 673: -/***/ ((__unused_webpack_module, exports) => { + return obj; +} -"use strict"; +function merge(defaults, route, options) { + if (typeof route === "string") { + let [method, url] = route.split(" "); + options = Object.assign(url ? { + method, + url + } : { + url: method + }, options); + } else { + options = Object.assign({}, route); + } // lowercase header names before merging with defaults to avoid duplicates -Object.defineProperty(exports, "__esModule", ({ value: true })); + options.headers = lowercaseKeys(options.headers); // remove properties with undefined values before merging -const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; -const REGEX_IS_INSTALLATION = /^ghs_/; -const REGEX_IS_USER_TO_SERVER = /^ghu_/; -async function auth(token) { - const isApp = token.split(/\./).length === 3; - const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); - const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); - const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; - return { - type: "token", - token: token, - tokenType - }; -} + removeUndefinedProperties(options); + removeUndefinedProperties(options.headers); + const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten -/** - * Prefix token for usage in the Authorization header - * - * @param token OAuth token or JSON Web Token - */ -function withAuthorizationPrefix(token) { - if (token.split(/\./).length === 3) { - return `bearer ${token}`; + if (defaults && defaults.mediaType.previews.length) { + mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews); } - return `token ${token}`; -} - -async function hook(token, request, route, parameters) { - const endpoint = request.endpoint.merge(route, parameters); - endpoint.headers.authorization = withAuthorizationPrefix(token); - return request(endpoint); + mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, "")); + return mergedOptions; } -const createTokenAuth = function createTokenAuth(token) { - if (!token) { - throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); - } +function addQueryParameters(url, parameters) { + const separator = /\?/.test(url) ? "&" : "?"; + const names = Object.keys(parameters); - if (typeof token !== "string") { - throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); + if (names.length === 0) { + return url; } - token = token.replace(/^(token|bearer) +/i, ""); - return Object.assign(auth.bind(null, token), { - hook: hook.bind(null, token) - }); -}; - -exports.createTokenAuth = createTokenAuth; -//# sourceMappingURL=index.js.map + return url + separator + names.map(name => { + if (name === "q") { + return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+"); + } + return `${name}=${encodeURIComponent(parameters[name])}`; + }).join("&"); +} -/***/ }), +const urlVariableRegex = /\{[^}]+\}/g; -/***/ 8525: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +function removeNonChars(variableName) { + return variableName.replace(/^\W+|\W+$/g, "").split(/,/); +} -"use strict"; +function extractUrlVariableNames(url) { + const matches = url.match(urlVariableRegex); + if (!matches) { + return []; + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []); +} -var universalUserAgent = __nccwpck_require__(5030); -var beforeAfterHook = __nccwpck_require__(3682); -var request = __nccwpck_require__(9353); -var graphql = __nccwpck_require__(6422); -var authToken = __nccwpck_require__(673); +function omit(object, keysToOmit) { + return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => { + obj[key] = object[key]; + return obj; + }, {}); +} -function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; +// Based on https://github.com/bramstein/url-template, licensed under BSD +// TODO: create separate package. +// +// Copyright (c) 2012-2014, Bram Stein +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } +/* istanbul ignore file */ +function encodeReserved(str) { + return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) { + if (!/%[0-9A-Fa-f]/.test(part)) { + part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); + } - return target; + return part; + }).join(""); } -function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - - var target = _objectWithoutPropertiesLoose(source, excluded); - - var key, i; +function encodeUnreserved(str) { + return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { + return "%" + c.charCodeAt(0).toString(16).toUpperCase(); + }); +} - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); +function encodeValue(operator, value, key) { + value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } + if (key) { + return encodeUnreserved(key) + "=" + value; + } else { + return value; } +} - return target; +function isDefined(value) { + return value !== undefined && value !== null; } -const VERSION = "3.6.0"; +function isKeyOperator(operator) { + return operator === ";" || operator === "&" || operator === "?"; +} -const _excluded = ["authStrategy"]; -class Octokit { - constructor(options = {}) { - const hook = new beforeAfterHook.Collection(); - const requestDefaults = { - baseUrl: request.request.endpoint.DEFAULTS.baseUrl, - headers: {}, - request: Object.assign({}, options.request, { - // @ts-ignore internal usage only, no need to type - hook: hook.bind(null, "request") - }), - mediaType: { - previews: [], - format: "" +function getValues(context, operator, key, modifier) { + var value = context[key], + result = []; + + if (isDefined(value) && value !== "") { + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + value = value.toString(); + + if (modifier && modifier !== "*") { + value = value.substring(0, parseInt(modifier, 10)); } - }; // prepend default user agent with `options.userAgent` if set - requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); + result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : "")); + } else { + if (modifier === "*") { + if (Array.isArray(value)) { + value.filter(isDefined).forEach(function (value) { + result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : "")); + }); + } else { + Object.keys(value).forEach(function (k) { + if (isDefined(value[k])) { + result.push(encodeValue(operator, value[k], k)); + } + }); + } + } else { + const tmp = []; - if (options.baseUrl) { - requestDefaults.baseUrl = options.baseUrl; - } + if (Array.isArray(value)) { + value.filter(isDefined).forEach(function (value) { + tmp.push(encodeValue(operator, value)); + }); + } else { + Object.keys(value).forEach(function (k) { + if (isDefined(value[k])) { + tmp.push(encodeUnreserved(k)); + tmp.push(encodeValue(operator, value[k].toString())); + } + }); + } - if (options.previews) { - requestDefaults.mediaType.previews = options.previews; + if (isKeyOperator(operator)) { + result.push(encodeUnreserved(key) + "=" + tmp.join(",")); + } else if (tmp.length !== 0) { + result.push(tmp.join(",")); + } + } } - - if (options.timeZone) { - requestDefaults.headers["time-zone"] = options.timeZone; + } else { + if (operator === ";") { + if (isDefined(value)) { + result.push(encodeUnreserved(key)); + } + } else if (value === "" && (operator === "&" || operator === "?")) { + result.push(encodeUnreserved(key) + "="); + } else if (value === "") { + result.push(""); } + } - this.request = request.request.defaults(requestDefaults); - this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); - this.log = Object.assign({ - debug: () => {}, - info: () => {}, - warn: console.warn.bind(console), - error: console.error.bind(console) - }, options.log); - this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance - // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. - // (2) If only `options.auth` is set, use the default token authentication strategy. - // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. - // TODO: type `options.auth` based on `options.authStrategy`. - - if (!options.authStrategy) { - if (!options.auth) { - // (1) - this.auth = async () => ({ - type: "unauthenticated" - }); - } else { - // (2) - const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } - } else { - const { - authStrategy - } = options, - otherOptions = _objectWithoutProperties(options, _excluded); + return result; +} - const auth = authStrategy(Object.assign({ - request: this.request, - log: this.log, - // we pass the current octokit instance as well as its constructor options - // to allow for authentication strategies that return a new octokit instance - // that shares the same internal state as the current one. The original - // requirement for this was the "event-octokit" authentication strategy - // of https://github.com/probot/octokit-auth-probot. - octokit: this, - octokitOptions: otherOptions - }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ +function parseUrl(template) { + return { + expand: expand.bind(null, template) + }; +} - hook.wrap("request", auth.hook); - this.auth = auth; - } // apply plugins - // https://stackoverflow.com/a/16345172 +function expand(template, context) { + var operators = ["+", "#", ".", "/", ";", "?", "&"]; + return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) { + if (expression) { + let operator = ""; + const values = []; + if (operators.indexOf(expression.charAt(0)) !== -1) { + operator = expression.charAt(0); + expression = expression.substr(1); + } - const classConstructor = this.constructor; - classConstructor.plugins.forEach(plugin => { - Object.assign(this, plugin(this, options)); - }); - } + expression.split(/,/g).forEach(function (variable) { + var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); + values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3])); + }); - static defaults(defaults) { - const OctokitWithDefaults = class extends this { - constructor(...args) { - const options = args[0] || {}; + if (operator && operator !== "+") { + var separator = ","; - if (typeof defaults === "function") { - super(defaults(options)); - return; + if (operator === "?") { + separator = "&"; + } else if (operator !== "#") { + separator = operator; } - super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { - userAgent: `${options.userAgent} ${defaults.userAgent}` - } : null)); + return (values.length !== 0 ? operator : "") + values.join(separator); + } else { + return values.join(","); } + } else { + return encodeReserved(literal); + } + }); +} - }; - return OctokitWithDefaults; - } - /** - * Attach a plugin (or many) to your Octokit instance. - * - * @example - * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) - */ +function parse(options) { + // https://fetch.spec.whatwg.org/#methods + let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible + let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); + let headers = Object.assign({}, options.headers); + let body; + let parameters = omit(options, ["method", "baseUrl", "url", "headers", "request", "mediaType"]); // extract variable names from URL to calculate remaining variables later - static plugin(...newPlugins) { - var _a; + const urlVariableNames = extractUrlVariableNames(url); + url = parseUrl(url).expand(parameters); - const currentPlugins = this.plugins; - const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); - return NewOctokit; + if (!/^http/.test(url)) { + url = options.baseUrl + url; } -} -Octokit.VERSION = VERSION; -Octokit.plugins = []; - -exports.Octokit = Octokit; -//# sourceMappingURL=index.js.map + const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat("baseUrl"); + const remainingParameters = omit(parameters, omittedParameters); + const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); + if (!isBinaryRequest) { + if (options.mediaType.format) { + // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw + headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(","); + } -/***/ }), + if (options.mediaType.previews.length) { + const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || []; + headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => { + const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; + return `application/vnd.github.${preview}-preview${format}`; + }).join(","); + } + } // for GET/HEAD requests, set URL query parameters from remaining parameters + // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters -/***/ 8713: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; + if (["GET", "HEAD"].includes(method)) { + url = addQueryParameters(url, remainingParameters); + } else { + if ("data" in remainingParameters) { + body = remainingParameters.data; + } else { + if (Object.keys(remainingParameters).length) { + body = remainingParameters; + } else { + headers["content-length"] = 0; + } + } + } // default content-type for JSON if body is set -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!headers["content-type"] && typeof body !== "undefined") { + headers["content-type"] = "application/json; charset=utf-8"; + } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body. + // fetch does not allow to set `content-length` header, but we can set body to an empty string -var isPlainObject = __nccwpck_require__(3287); -var universalUserAgent = __nccwpck_require__(5030); -function lowercaseKeys(object) { - if (!object) { - return {}; - } + if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") { + body = ""; + } // Only return body/request keys if present - return Object.keys(object).reduce((newObj, key) => { - newObj[key.toLowerCase()] = object[key]; - return newObj; - }, {}); -} -function mergeDeep(defaults, options) { - const result = Object.assign({}, defaults); - Object.keys(options).forEach(key => { - if (isPlainObject.isPlainObject(options[key])) { - if (!(key in defaults)) Object.assign(result, { - [key]: options[key] - });else result[key] = mergeDeep(defaults[key], options[key]); - } else { - Object.assign(result, { - [key]: options[key] - }); - } + return Object.assign({ + method, + url, + headers + }, typeof body !== "undefined" ? { + body + } : null, options.request ? { + request: options.request + } : null); +} + +function endpointWithDefaults(defaults, route, options) { + return parse(merge(defaults, route, options)); +} + +function withDefaults(oldDefaults, newDefaults) { + const DEFAULTS = merge(oldDefaults, newDefaults); + const endpoint = endpointWithDefaults.bind(null, DEFAULTS); + return Object.assign(endpoint, { + DEFAULTS, + defaults: withDefaults.bind(null, DEFAULTS), + merge: merge.bind(null, DEFAULTS), + parse }); - return result; } -function removeUndefinedProperties(obj) { - for (const key in obj) { - if (obj[key] === undefined) { - delete obj[key]; - } +const VERSION = "6.0.12"; + +const userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url. +// So we use RequestParameters and add method as additional required property. + +const DEFAULTS = { + method: "GET", + baseUrl: "https://api.github.com", + headers: { + accept: "application/vnd.github.v3+json", + "user-agent": userAgent + }, + mediaType: { + format: "", + previews: [] } +}; - return obj; -} +const endpoint = withDefaults(null, DEFAULTS); -function merge(defaults, route, options) { - if (typeof route === "string") { - let [method, url] = route.split(" "); - options = Object.assign(url ? { - method, - url - } : { - url: method - }, options); - } else { - options = Object.assign({}, route); - } // lowercase header names before merging with defaults to avoid duplicates +exports.endpoint = endpoint; +//# sourceMappingURL=index.js.map - options.headers = lowercaseKeys(options.headers); // remove properties with undefined values before merging +/***/ }), - removeUndefinedProperties(options); - removeUndefinedProperties(options.headers); - const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten +/***/ 6422: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (defaults && defaults.mediaType.previews.length) { - mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews); - } +"use strict"; - mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, "")); - return mergedOptions; -} -function addQueryParameters(url, parameters) { - const separator = /\?/.test(url) ? "&" : "?"; - const names = Object.keys(parameters); +Object.defineProperty(exports, "__esModule", ({ value: true })); - if (names.length === 0) { - return url; - } +var request = __nccwpck_require__(9353); +var universalUserAgent = __nccwpck_require__(5030); - return url + separator + names.map(name => { - if (name === "q") { - return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+"); - } +const VERSION = "4.8.0"; - return `${name}=${encodeURIComponent(parameters[name])}`; - }).join("&"); +function _buildMessageForResponseErrors(data) { + return `Request failed due to following response errors:\n` + data.errors.map(e => ` - ${e.message}`).join("\n"); } -const urlVariableRegex = /\{[^}]+\}/g; +class GraphqlResponseError extends Error { + constructor(request, headers, response) { + super(_buildMessageForResponseErrors(response)); + this.request = request; + this.headers = headers; + this.response = response; + this.name = "GraphqlResponseError"; // Expose the errors and response data in their shorthand properties. -function removeNonChars(variableName) { - return variableName.replace(/^\W+|\W+$/g, "").split(/,/); -} + this.errors = response.errors; + this.data = response.data; // Maintains proper stack trace (only available on V8) -function extractUrlVariableNames(url) { - const matches = url.match(urlVariableRegex); + /* istanbul ignore next */ - if (!matches) { - return []; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } } - return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []); } -function omit(object, keysToOmit) { - return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => { - obj[key] = object[key]; - return obj; - }, {}); -} +const NON_VARIABLE_OPTIONS = ["method", "baseUrl", "url", "headers", "request", "query", "mediaType"]; +const FORBIDDEN_VARIABLE_OPTIONS = ["query", "method", "url"]; +const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/; +function graphql(request, query, options) { + if (options) { + if (typeof query === "string" && "query" in options) { + return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`)); + } -// Based on https://github.com/bramstein/url-template, licensed under BSD -// TODO: create separate package. -// -// Copyright (c) 2012-2014, Bram Stein -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + for (const key in options) { + if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) continue; + return Promise.reject(new Error(`[@octokit/graphql] "${key}" cannot be used as variable name`)); + } + } -/* istanbul ignore file */ -function encodeReserved(str) { - return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) { - if (!/%[0-9A-Fa-f]/.test(part)) { - part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); + const parsedOptions = typeof query === "string" ? Object.assign({ + query + }, options) : query; + const requestOptions = Object.keys(parsedOptions).reduce((result, key) => { + if (NON_VARIABLE_OPTIONS.includes(key)) { + result[key] = parsedOptions[key]; + return result; } - return part; - }).join(""); -} + if (!result.variables) { + result.variables = {}; + } -function encodeUnreserved(str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { - return "%" + c.charCodeAt(0).toString(16).toUpperCase(); - }); -} + result.variables[key] = parsedOptions[key]; + return result; + }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix + // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451 -function encodeValue(operator, value, key) { - value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); + const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl; - if (key) { - return encodeUnreserved(key) + "=" + value; - } else { - return value; + if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) { + requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql"); } + + return request(requestOptions).then(response => { + if (response.data.errors) { + const headers = {}; + + for (const key of Object.keys(response.headers)) { + headers[key] = response.headers[key]; + } + + throw new GraphqlResponseError(requestOptions, headers, response.data); + } + + return response.data.data; + }); } -function isDefined(value) { - return value !== undefined && value !== null; +function withDefaults(request$1, newDefaults) { + const newRequest = request$1.defaults(newDefaults); + + const newApi = (query, options) => { + return graphql(newRequest, query, options); + }; + + return Object.assign(newApi, { + defaults: withDefaults.bind(null, newRequest), + endpoint: request.request.endpoint + }); } -function isKeyOperator(operator) { - return operator === ";" || operator === "&" || operator === "?"; +const graphql$1 = withDefaults(request.request, { + headers: { + "user-agent": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}` + }, + method: "POST", + url: "/graphql" +}); +function withCustomRequest(customRequest) { + return withDefaults(customRequest, { + method: "POST", + url: "/graphql" + }); } -function getValues(context, operator, key, modifier) { - var value = context[key], - result = []; +exports.GraphqlResponseError = GraphqlResponseError; +exports.graphql = graphql$1; +exports.withCustomRequest = withCustomRequest; +//# sourceMappingURL=index.js.map - if (isDefined(value) && value !== "") { - if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { - value = value.toString(); - if (modifier && modifier !== "*") { - value = value.substring(0, parseInt(modifier, 10)); - } +/***/ }), - result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : "")); - } else { - if (modifier === "*") { - if (Array.isArray(value)) { - value.filter(isDefined).forEach(function (value) { - result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : "")); - }); - } else { - Object.keys(value).forEach(function (k) { - if (isDefined(value[k])) { - result.push(encodeValue(operator, value[k], k)); - } - }); - } - } else { - const tmp = []; +/***/ 8945: +/***/ ((__unused_webpack_module, exports) => { - if (Array.isArray(value)) { - value.filter(isDefined).forEach(function (value) { - tmp.push(encodeValue(operator, value)); - }); - } else { - Object.keys(value).forEach(function (k) { - if (isDefined(value[k])) { - tmp.push(encodeUnreserved(k)); - tmp.push(encodeValue(operator, value[k].toString())); - } - }); - } +"use strict"; - if (isKeyOperator(operator)) { - result.push(encodeUnreserved(key) + "=" + tmp.join(",")); - } else if (tmp.length !== 0) { - result.push(tmp.join(",")); - } - } - } - } else { - if (operator === ";") { - if (isDefined(value)) { - result.push(encodeUnreserved(key)); - } - } else if (value === "" && (operator === "&" || operator === "?")) { - result.push(encodeUnreserved(key) + "="); - } else if (value === "") { - result.push(""); - } - } - return result; -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -function parseUrl(template) { - return { - expand: expand.bind(null, template) - }; -} +const VERSION = "2.21.3"; -function expand(template, context) { - var operators = ["+", "#", ".", "/", ";", "?", "&"]; - return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) { - if (expression) { - let operator = ""; - const values = []; +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); - if (operators.indexOf(expression.charAt(0)) !== -1) { - operator = expression.charAt(0); - expression = expression.substr(1); - } + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + enumerableOnly && (symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + })), keys.push.apply(keys, symbols); + } - expression.split(/,/g).forEach(function (variable) { - var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); - values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3])); - }); + return keys; +} - if (operator && operator !== "+") { - var separator = ","; +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = null != arguments[i] ? arguments[i] : {}; + i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { + _defineProperty(target, key, source[key]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } - if (operator === "?") { - separator = "&"; - } else if (operator !== "#") { - separator = operator; - } + return target; +} - return (values.length !== 0 ? operator : "") + values.join(separator); - } else { - return values.join(","); - } - } else { - return encodeReserved(literal); - } - }); +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; } -function parse(options) { - // https://fetch.spec.whatwg.org/#methods - let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible +/** + * Some “list” response that can be paginated have a different response structure + * + * They have a `total_count` key in the response (search also has `incomplete_results`, + * /installation/repositories also has `repository_selection`), as well as a key with + * the list of the items which name varies from endpoint to endpoint. + * + * Octokit normalizes these responses so that paginated results are always returned following + * the same structure. One challenge is that if the list response has only one page, no Link + * header is provided, so this header alone is not sufficient to check wether a response is + * paginated or not. + * + * We check if a "total_count" key is present in the response data, but also make sure that + * a "url" property is not, as the "Get the combined status for a specific ref" endpoint would + * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref + */ +function normalizePaginatedListResponse(response) { + // endpoints can respond with 204 if repository is empty + if (!response.data) { + return _objectSpread2(_objectSpread2({}, response), {}, { + data: [] + }); + } - let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); - let headers = Object.assign({}, options.headers); - let body; - let parameters = omit(options, ["method", "baseUrl", "url", "headers", "request", "mediaType"]); // extract variable names from URL to calculate remaining variables later + const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data); + if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way + // to retrieve the same information. - const urlVariableNames = extractUrlVariableNames(url); - url = parseUrl(url).expand(parameters); + const incompleteResults = response.data.incomplete_results; + const repositorySelection = response.data.repository_selection; + const totalCount = response.data.total_count; + delete response.data.incomplete_results; + delete response.data.repository_selection; + delete response.data.total_count; + const namespaceKey = Object.keys(response.data)[0]; + const data = response.data[namespaceKey]; + response.data = data; - if (!/^http/.test(url)) { - url = options.baseUrl + url; + if (typeof incompleteResults !== "undefined") { + response.data.incomplete_results = incompleteResults; } - const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat("baseUrl"); - const remainingParameters = omit(parameters, omittedParameters); - const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); + if (typeof repositorySelection !== "undefined") { + response.data.repository_selection = repositorySelection; + } - if (!isBinaryRequest) { - if (options.mediaType.format) { - // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw - headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(","); - } + response.data.total_count = totalCount; + return response; +} - if (options.mediaType.previews.length) { - const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || []; - headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => { - const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; - return `application/vnd.github.${preview}-preview${format}`; - }).join(","); - } - } // for GET/HEAD requests, set URL query parameters from remaining parameters - // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters +function iterator(octokit, route, parameters) { + const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters); + const requestMethod = typeof route === "function" ? route : octokit.request; + const method = options.method; + const headers = options.headers; + let url = options.url; + return { + [Symbol.asyncIterator]: () => ({ + async next() { + if (!url) return { + done: true + }; + try { + const response = await requestMethod({ + method, + url, + headers + }); + const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format: + // '; rel="next", ; rel="last"' + // sets `url` to undefined if "next" URL is not present or `link` header is not set - if (["GET", "HEAD"].includes(method)) { - url = addQueryParameters(url, remainingParameters); - } else { - if ("data" in remainingParameters) { - body = remainingParameters.data; - } else { - if (Object.keys(remainingParameters).length) { - body = remainingParameters; - } else { - headers["content-length"] = 0; + url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1]; + return { + value: normalizedResponse + }; + } catch (error) { + if (error.status !== 409) throw error; + url = ""; + return { + value: { + status: 200, + headers: {}, + data: [] + } + }; + } } - } - } // default content-type for JSON if body is set + }) + }; +} - if (!headers["content-type"] && typeof body !== "undefined") { - headers["content-type"] = "application/json; charset=utf-8"; - } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body. - // fetch does not allow to set `content-length` header, but we can set body to an empty string +function paginate(octokit, route, parameters, mapFn) { + if (typeof parameters === "function") { + mapFn = parameters; + parameters = undefined; + } + return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn); +} - if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") { - body = ""; - } // Only return body/request keys if present +function gather(octokit, results, iterator, mapFn) { + return iterator.next().then(result => { + if (result.done) { + return results; + } + let earlyExit = false; - return Object.assign({ - method, - url, - headers - }, typeof body !== "undefined" ? { - body - } : null, options.request ? { - request: options.request - } : null); -} + function done() { + earlyExit = true; + } -function endpointWithDefaults(defaults, route, options) { - return parse(merge(defaults, route, options)); -} + results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data); -function withDefaults(oldDefaults, newDefaults) { - const DEFAULTS = merge(oldDefaults, newDefaults); - const endpoint = endpointWithDefaults.bind(null, DEFAULTS); - return Object.assign(endpoint, { - DEFAULTS, - defaults: withDefaults.bind(null, DEFAULTS), - merge: merge.bind(null, DEFAULTS), - parse + if (earlyExit) { + return results; + } + + return gather(octokit, results, iterator, mapFn); }); } -const VERSION = "6.0.12"; +const composePaginateRest = Object.assign(paginate, { + iterator +}); -const userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url. -// So we use RequestParameters and add method as additional required property. +const paginatingEndpoints = ["GET /app/hook/deliveries", "GET /app/installations", "GET /applications/grants", "GET /authorizations", "GET /enterprises/{enterprise}/actions/permissions/organizations", "GET /enterprises/{enterprise}/actions/runner-groups", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners", "GET /enterprises/{enterprise}/actions/runners", "GET /enterprises/{enterprise}/audit-log", "GET /enterprises/{enterprise}/secret-scanning/alerts", "GET /enterprises/{enterprise}/settings/billing/advanced-security", "GET /events", "GET /gists", "GET /gists/public", "GET /gists/starred", "GET /gists/{gist_id}/comments", "GET /gists/{gist_id}/commits", "GET /gists/{gist_id}/forks", "GET /installation/repositories", "GET /issues", "GET /licenses", "GET /marketplace_listing/plans", "GET /marketplace_listing/plans/{plan_id}/accounts", "GET /marketplace_listing/stubbed/plans", "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts", "GET /networks/{owner}/{repo}/events", "GET /notifications", "GET /organizations", "GET /orgs/{org}/actions/cache/usage-by-repository", "GET /orgs/{org}/actions/permissions/repositories", "GET /orgs/{org}/actions/runner-groups", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners", "GET /orgs/{org}/actions/runners", "GET /orgs/{org}/actions/secrets", "GET /orgs/{org}/actions/secrets/{secret_name}/repositories", "GET /orgs/{org}/audit-log", "GET /orgs/{org}/blocks", "GET /orgs/{org}/code-scanning/alerts", "GET /orgs/{org}/codespaces", "GET /orgs/{org}/credential-authorizations", "GET /orgs/{org}/dependabot/secrets", "GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories", "GET /orgs/{org}/events", "GET /orgs/{org}/external-groups", "GET /orgs/{org}/failed_invitations", "GET /orgs/{org}/hooks", "GET /orgs/{org}/hooks/{hook_id}/deliveries", "GET /orgs/{org}/installations", "GET /orgs/{org}/invitations", "GET /orgs/{org}/invitations/{invitation_id}/teams", "GET /orgs/{org}/issues", "GET /orgs/{org}/members", "GET /orgs/{org}/migrations", "GET /orgs/{org}/migrations/{migration_id}/repositories", "GET /orgs/{org}/outside_collaborators", "GET /orgs/{org}/packages", "GET /orgs/{org}/packages/{package_type}/{package_name}/versions", "GET /orgs/{org}/projects", "GET /orgs/{org}/public_members", "GET /orgs/{org}/repos", "GET /orgs/{org}/secret-scanning/alerts", "GET /orgs/{org}/settings/billing/advanced-security", "GET /orgs/{org}/team-sync/groups", "GET /orgs/{org}/teams", "GET /orgs/{org}/teams/{team_slug}/discussions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/invitations", "GET /orgs/{org}/teams/{team_slug}/members", "GET /orgs/{org}/teams/{team_slug}/projects", "GET /orgs/{org}/teams/{team_slug}/repos", "GET /orgs/{org}/teams/{team_slug}/teams", "GET /projects/columns/{column_id}/cards", "GET /projects/{project_id}/collaborators", "GET /projects/{project_id}/columns", "GET /repos/{owner}/{repo}/actions/artifacts", "GET /repos/{owner}/{repo}/actions/caches", "GET /repos/{owner}/{repo}/actions/runners", "GET /repos/{owner}/{repo}/actions/runs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs", "GET /repos/{owner}/{repo}/actions/secrets", "GET /repos/{owner}/{repo}/actions/workflows", "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs", "GET /repos/{owner}/{repo}/assignees", "GET /repos/{owner}/{repo}/branches", "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations", "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs", "GET /repos/{owner}/{repo}/code-scanning/alerts", "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", "GET /repos/{owner}/{repo}/code-scanning/analyses", "GET /repos/{owner}/{repo}/codespaces", "GET /repos/{owner}/{repo}/codespaces/devcontainers", "GET /repos/{owner}/{repo}/codespaces/secrets", "GET /repos/{owner}/{repo}/collaborators", "GET /repos/{owner}/{repo}/comments", "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/commits", "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments", "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls", "GET /repos/{owner}/{repo}/commits/{ref}/check-runs", "GET /repos/{owner}/{repo}/commits/{ref}/check-suites", "GET /repos/{owner}/{repo}/commits/{ref}/status", "GET /repos/{owner}/{repo}/commits/{ref}/statuses", "GET /repos/{owner}/{repo}/contributors", "GET /repos/{owner}/{repo}/dependabot/secrets", "GET /repos/{owner}/{repo}/deployments", "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses", "GET /repos/{owner}/{repo}/environments", "GET /repos/{owner}/{repo}/events", "GET /repos/{owner}/{repo}/forks", "GET /repos/{owner}/{repo}/git/matching-refs/{ref}", "GET /repos/{owner}/{repo}/hooks", "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", "GET /repos/{owner}/{repo}/invitations", "GET /repos/{owner}/{repo}/issues", "GET /repos/{owner}/{repo}/issues/comments", "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/issues/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/comments", "GET /repos/{owner}/{repo}/issues/{issue_number}/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/labels", "GET /repos/{owner}/{repo}/issues/{issue_number}/reactions", "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline", "GET /repos/{owner}/{repo}/keys", "GET /repos/{owner}/{repo}/labels", "GET /repos/{owner}/{repo}/milestones", "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels", "GET /repos/{owner}/{repo}/notifications", "GET /repos/{owner}/{repo}/pages/builds", "GET /repos/{owner}/{repo}/projects", "GET /repos/{owner}/{repo}/pulls", "GET /repos/{owner}/{repo}/pulls/comments", "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments", "GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", "GET /repos/{owner}/{repo}/pulls/{pull_number}/files", "GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments", "GET /repos/{owner}/{repo}/releases", "GET /repos/{owner}/{repo}/releases/{release_id}/assets", "GET /repos/{owner}/{repo}/releases/{release_id}/reactions", "GET /repos/{owner}/{repo}/secret-scanning/alerts", "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations", "GET /repos/{owner}/{repo}/stargazers", "GET /repos/{owner}/{repo}/subscribers", "GET /repos/{owner}/{repo}/tags", "GET /repos/{owner}/{repo}/teams", "GET /repos/{owner}/{repo}/topics", "GET /repositories", "GET /repositories/{repository_id}/environments/{environment_name}/secrets", "GET /search/code", "GET /search/commits", "GET /search/issues", "GET /search/labels", "GET /search/repositories", "GET /search/topics", "GET /search/users", "GET /teams/{team_id}/discussions", "GET /teams/{team_id}/discussions/{discussion_number}/comments", "GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /teams/{team_id}/discussions/{discussion_number}/reactions", "GET /teams/{team_id}/invitations", "GET /teams/{team_id}/members", "GET /teams/{team_id}/projects", "GET /teams/{team_id}/repos", "GET /teams/{team_id}/teams", "GET /user/blocks", "GET /user/codespaces", "GET /user/codespaces/secrets", "GET /user/emails", "GET /user/followers", "GET /user/following", "GET /user/gpg_keys", "GET /user/installations", "GET /user/installations/{installation_id}/repositories", "GET /user/issues", "GET /user/keys", "GET /user/marketplace_purchases", "GET /user/marketplace_purchases/stubbed", "GET /user/memberships/orgs", "GET /user/migrations", "GET /user/migrations/{migration_id}/repositories", "GET /user/orgs", "GET /user/packages", "GET /user/packages/{package_type}/{package_name}/versions", "GET /user/public_emails", "GET /user/repos", "GET /user/repository_invitations", "GET /user/starred", "GET /user/subscriptions", "GET /user/teams", "GET /users", "GET /users/{username}/events", "GET /users/{username}/events/orgs/{org}", "GET /users/{username}/events/public", "GET /users/{username}/followers", "GET /users/{username}/following", "GET /users/{username}/gists", "GET /users/{username}/gpg_keys", "GET /users/{username}/keys", "GET /users/{username}/orgs", "GET /users/{username}/packages", "GET /users/{username}/projects", "GET /users/{username}/received_events", "GET /users/{username}/received_events/public", "GET /users/{username}/repos", "GET /users/{username}/starred", "GET /users/{username}/subscriptions"]; -const DEFAULTS = { - method: "GET", - baseUrl: "https://api.github.com", - headers: { - accept: "application/vnd.github.v3+json", - "user-agent": userAgent - }, - mediaType: { - format: "", - previews: [] +function isPaginatingEndpoint(arg) { + if (typeof arg === "string") { + return paginatingEndpoints.includes(arg); + } else { + return false; } -}; +} -const endpoint = withDefaults(null, DEFAULTS); +/** + * @param octokit Octokit instance + * @param options Options passed to Octokit constructor + */ -exports.endpoint = endpoint; +function paginateRest(octokit) { + return { + paginate: Object.assign(paginate.bind(null, octokit), { + iterator: iterator.bind(null, octokit) + }) + }; +} +paginateRest.VERSION = VERSION; + +exports.composePaginateRest = composePaginateRest; +exports.isPaginatingEndpoint = isPaginatingEndpoint; +exports.paginateRest = paginateRest; +exports.paginatingEndpoints = paginatingEndpoints; //# sourceMappingURL=index.js.map /***/ }), -/***/ 6422: +/***/ 7471: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -2713,691 +2506,352 @@ exports.endpoint = endpoint; Object.defineProperty(exports, "__esModule", ({ value: true })); -var request = __nccwpck_require__(9353); -var universalUserAgent = __nccwpck_require__(5030); - -const VERSION = "4.8.0"; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -function _buildMessageForResponseErrors(data) { - return `Request failed due to following response errors:\n` + data.errors.map(e => ` - ${e.message}`).join("\n"); -} +var deprecation = __nccwpck_require__(8932); +var once = _interopDefault(__nccwpck_require__(1223)); -class GraphqlResponseError extends Error { - constructor(request, headers, response) { - super(_buildMessageForResponseErrors(response)); - this.request = request; - this.headers = headers; - this.response = response; - this.name = "GraphqlResponseError"; // Expose the errors and response data in their shorthand properties. +const logOnceCode = once(deprecation => console.warn(deprecation)); +const logOnceHeaders = once(deprecation => console.warn(deprecation)); +/** + * Error with extra properties to help with debugging + */ - this.errors = response.errors; - this.data = response.data; // Maintains proper stack trace (only available on V8) +class RequestError extends Error { + constructor(message, statusCode, options) { + super(message); // Maintains proper stack trace (only available on V8) /* istanbul ignore next */ if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } - } - -} - -const NON_VARIABLE_OPTIONS = ["method", "baseUrl", "url", "headers", "request", "query", "mediaType"]; -const FORBIDDEN_VARIABLE_OPTIONS = ["query", "method", "url"]; -const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/; -function graphql(request, query, options) { - if (options) { - if (typeof query === "string" && "query" in options) { - return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`)); - } - - for (const key in options) { - if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) continue; - return Promise.reject(new Error(`[@octokit/graphql] "${key}" cannot be used as variable name`)); - } - } - const parsedOptions = typeof query === "string" ? Object.assign({ - query - }, options) : query; - const requestOptions = Object.keys(parsedOptions).reduce((result, key) => { - if (NON_VARIABLE_OPTIONS.includes(key)) { - result[key] = parsedOptions[key]; - return result; - } + this.name = "HttpError"; + this.status = statusCode; + let headers; - if (!result.variables) { - result.variables = {}; + if ("headers" in options && typeof options.headers !== "undefined") { + headers = options.headers; } - result.variables[key] = parsedOptions[key]; - return result; - }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix - // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451 - - const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl; - - if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) { - requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql"); - } + if ("response" in options) { + this.response = options.response; + headers = options.response.headers; + } // redact request credentials without mutating original request options - return request(requestOptions).then(response => { - if (response.data.errors) { - const headers = {}; - for (const key of Object.keys(response.headers)) { - headers[key] = response.headers[key]; - } + const requestCopy = Object.assign({}, options.request); - throw new GraphqlResponseError(requestOptions, headers, response.data); + if (options.request.headers.authorization) { + requestCopy.headers = Object.assign({}, options.request.headers, { + authorization: options.request.headers.authorization.replace(/ .*$/, " [REDACTED]") + }); } - return response.data.data; - }); -} + requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit + // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications + .replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]") // OAuth tokens can be passed as URL query parameters, although it is not recommended + // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header + .replace(/\baccess_token=\w+/g, "access_token=[REDACTED]"); + this.request = requestCopy; // deprecations -function withDefaults(request$1, newDefaults) { - const newRequest = request$1.defaults(newDefaults); + Object.defineProperty(this, "code", { + get() { + logOnceCode(new deprecation.Deprecation("[@octokit/request-error] `error.code` is deprecated, use `error.status`.")); + return statusCode; + } - const newApi = (query, options) => { - return graphql(newRequest, query, options); - }; + }); + Object.defineProperty(this, "headers", { + get() { + logOnceHeaders(new deprecation.Deprecation("[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`.")); + return headers || {}; + } - return Object.assign(newApi, { - defaults: withDefaults.bind(null, newRequest), - endpoint: request.request.endpoint - }); -} + }); + } -const graphql$1 = withDefaults(request.request, { - headers: { - "user-agent": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}` - }, - method: "POST", - url: "/graphql" -}); -function withCustomRequest(customRequest) { - return withDefaults(customRequest, { - method: "POST", - url: "/graphql" - }); } -exports.GraphqlResponseError = GraphqlResponseError; -exports.graphql = graphql$1; -exports.withCustomRequest = withCustomRequest; +exports.RequestError = RequestError; //# sourceMappingURL=index.js.map /***/ }), -/***/ 8945: -/***/ ((__unused_webpack_module, exports) => { +/***/ 9353: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -const VERSION = "2.21.3"; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -function ownKeys(object, enumerableOnly) { - var keys = Object.keys(object); +var endpoint = __nccwpck_require__(8713); +var universalUserAgent = __nccwpck_require__(5030); +var isPlainObject = __nccwpck_require__(3287); +var nodeFetch = _interopDefault(__nccwpck_require__(467)); +var requestError = __nccwpck_require__(7471); - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(object); - enumerableOnly && (symbols = symbols.filter(function (sym) { - return Object.getOwnPropertyDescriptor(object, sym).enumerable; - })), keys.push.apply(keys, symbols); - } +const VERSION = "5.6.3"; - return keys; +function getBufferResponse(response) { + return response.arrayBuffer(); } -function _objectSpread2(target) { - for (var i = 1; i < arguments.length; i++) { - var source = null != arguments[i] ? arguments[i] : {}; - i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { - _defineProperty(target, key, source[key]); - }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { - Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); - }); +function fetchWrapper(requestOptions) { + const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console; + + if (isPlainObject.isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) { + requestOptions.body = JSON.stringify(requestOptions.body); } - return target; -} + let headers = {}; + let status; + let url; + const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch; + return fetch(requestOptions.url, Object.assign({ + method: requestOptions.method, + body: requestOptions.body, + headers: requestOptions.headers, + redirect: requestOptions.redirect + }, // `requestOptions.request.agent` type is incompatible + // see https://github.com/octokit/types.ts/pull/264 + requestOptions.request)).then(async response => { + url = response.url; + status = response.status; -function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } + for (const keyAndValue of response.headers) { + headers[keyAndValue[0]] = keyAndValue[1]; + } - return obj; -} + if ("deprecation" in headers) { + const matches = headers.link && headers.link.match(/<([^>]+)>; rel="deprecation"/); + const deprecationLink = matches && matches.pop(); + log.warn(`[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}`); + } -/** - * Some “list” response that can be paginated have a different response structure - * - * They have a `total_count` key in the response (search also has `incomplete_results`, - * /installation/repositories also has `repository_selection`), as well as a key with - * the list of the items which name varies from endpoint to endpoint. - * - * Octokit normalizes these responses so that paginated results are always returned following - * the same structure. One challenge is that if the list response has only one page, no Link - * header is provided, so this header alone is not sufficient to check wether a response is - * paginated or not. - * - * We check if a "total_count" key is present in the response data, but also make sure that - * a "url" property is not, as the "Get the combined status for a specific ref" endpoint would - * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref - */ -function normalizePaginatedListResponse(response) { - // endpoints can respond with 204 if repository is empty - if (!response.data) { - return _objectSpread2(_objectSpread2({}, response), {}, { - data: [] - }); - } + if (status === 204 || status === 205) { + return; + } // GitHub API returns 200 for HEAD requests - const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data); - if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way - // to retrieve the same information. - const incompleteResults = response.data.incomplete_results; - const repositorySelection = response.data.repository_selection; - const totalCount = response.data.total_count; - delete response.data.incomplete_results; - delete response.data.repository_selection; - delete response.data.total_count; - const namespaceKey = Object.keys(response.data)[0]; - const data = response.data[namespaceKey]; - response.data = data; + if (requestOptions.method === "HEAD") { + if (status < 400) { + return; + } - if (typeof incompleteResults !== "undefined") { - response.data.incomplete_results = incompleteResults; - } + throw new requestError.RequestError(response.statusText, status, { + response: { + url, + status, + headers, + data: undefined + }, + request: requestOptions + }); + } - if (typeof repositorySelection !== "undefined") { - response.data.repository_selection = repositorySelection; - } + if (status === 304) { + throw new requestError.RequestError("Not modified", status, { + response: { + url, + status, + headers, + data: await getResponseData(response) + }, + request: requestOptions + }); + } - response.data.total_count = totalCount; - return response; + if (status >= 400) { + const data = await getResponseData(response); + const error = new requestError.RequestError(toErrorMessage(data), status, { + response: { + url, + status, + headers, + data + }, + request: requestOptions + }); + throw error; + } + + return getResponseData(response); + }).then(data => { + return { + status, + url, + headers, + data + }; + }).catch(error => { + if (error instanceof requestError.RequestError) throw error; + throw new requestError.RequestError(error.message, 500, { + request: requestOptions + }); + }); } -function iterator(octokit, route, parameters) { - const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters); - const requestMethod = typeof route === "function" ? route : octokit.request; - const method = options.method; - const headers = options.headers; - let url = options.url; - return { - [Symbol.asyncIterator]: () => ({ - async next() { - if (!url) return { - done: true - }; +async function getResponseData(response) { + const contentType = response.headers.get("content-type"); - try { - const response = await requestMethod({ - method, - url, - headers - }); - const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format: - // '; rel="next", ; rel="last"' - // sets `url` to undefined if "next" URL is not present or `link` header is not set + if (/application\/json/.test(contentType)) { + return response.json(); + } - url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1]; - return { - value: normalizedResponse - }; - } catch (error) { - if (error.status !== 409) throw error; - url = ""; - return { - value: { - status: 200, - headers: {}, - data: [] - } - }; - } - } + if (!contentType || /^text\/|charset=utf-8$/.test(contentType)) { + return response.text(); + } - }) - }; + return getBufferResponse(response); } -function paginate(octokit, route, parameters, mapFn) { - if (typeof parameters === "function") { - mapFn = parameters; - parameters = undefined; - } +function toErrorMessage(data) { + if (typeof data === "string") return data; // istanbul ignore else - just in case - return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn); + if ("message" in data) { + if (Array.isArray(data.errors)) { + return `${data.message}: ${data.errors.map(JSON.stringify).join(", ")}`; + } + + return data.message; + } // istanbul ignore next - just in case + + + return `Unknown error: ${JSON.stringify(data)}`; } -function gather(octokit, results, iterator, mapFn) { - return iterator.next().then(result => { - if (result.done) { - return results; - } +function withDefaults(oldEndpoint, newDefaults) { + const endpoint = oldEndpoint.defaults(newDefaults); - let earlyExit = false; + const newApi = function (route, parameters) { + const endpointOptions = endpoint.merge(route, parameters); - function done() { - earlyExit = true; + if (!endpointOptions.request || !endpointOptions.request.hook) { + return fetchWrapper(endpoint.parse(endpointOptions)); } - results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data); + const request = (route, parameters) => { + return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters))); + }; - if (earlyExit) { - return results; - } + Object.assign(request, { + endpoint, + defaults: withDefaults.bind(null, endpoint) + }); + return endpointOptions.request.hook(request, endpointOptions); + }; - return gather(octokit, results, iterator, mapFn); + return Object.assign(newApi, { + endpoint, + defaults: withDefaults.bind(null, endpoint) }); } -const composePaginateRest = Object.assign(paginate, { - iterator +const request = withDefaults(endpoint.endpoint, { + headers: { + "user-agent": `octokit-request.js/${VERSION} ${universalUserAgent.getUserAgent()}` + } }); -const paginatingEndpoints = ["GET /app/hook/deliveries", "GET /app/installations", "GET /applications/grants", "GET /authorizations", "GET /enterprises/{enterprise}/actions/permissions/organizations", "GET /enterprises/{enterprise}/actions/runner-groups", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners", "GET /enterprises/{enterprise}/actions/runners", "GET /enterprises/{enterprise}/audit-log", "GET /enterprises/{enterprise}/secret-scanning/alerts", "GET /enterprises/{enterprise}/settings/billing/advanced-security", "GET /events", "GET /gists", "GET /gists/public", "GET /gists/starred", "GET /gists/{gist_id}/comments", "GET /gists/{gist_id}/commits", "GET /gists/{gist_id}/forks", "GET /installation/repositories", "GET /issues", "GET /licenses", "GET /marketplace_listing/plans", "GET /marketplace_listing/plans/{plan_id}/accounts", "GET /marketplace_listing/stubbed/plans", "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts", "GET /networks/{owner}/{repo}/events", "GET /notifications", "GET /organizations", "GET /orgs/{org}/actions/cache/usage-by-repository", "GET /orgs/{org}/actions/permissions/repositories", "GET /orgs/{org}/actions/runner-groups", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners", "GET /orgs/{org}/actions/runners", "GET /orgs/{org}/actions/secrets", "GET /orgs/{org}/actions/secrets/{secret_name}/repositories", "GET /orgs/{org}/audit-log", "GET /orgs/{org}/blocks", "GET /orgs/{org}/code-scanning/alerts", "GET /orgs/{org}/codespaces", "GET /orgs/{org}/credential-authorizations", "GET /orgs/{org}/dependabot/secrets", "GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories", "GET /orgs/{org}/events", "GET /orgs/{org}/external-groups", "GET /orgs/{org}/failed_invitations", "GET /orgs/{org}/hooks", "GET /orgs/{org}/hooks/{hook_id}/deliveries", "GET /orgs/{org}/installations", "GET /orgs/{org}/invitations", "GET /orgs/{org}/invitations/{invitation_id}/teams", "GET /orgs/{org}/issues", "GET /orgs/{org}/members", "GET /orgs/{org}/migrations", "GET /orgs/{org}/migrations/{migration_id}/repositories", "GET /orgs/{org}/outside_collaborators", "GET /orgs/{org}/packages", "GET /orgs/{org}/packages/{package_type}/{package_name}/versions", "GET /orgs/{org}/projects", "GET /orgs/{org}/public_members", "GET /orgs/{org}/repos", "GET /orgs/{org}/secret-scanning/alerts", "GET /orgs/{org}/settings/billing/advanced-security", "GET /orgs/{org}/team-sync/groups", "GET /orgs/{org}/teams", "GET /orgs/{org}/teams/{team_slug}/discussions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/invitations", "GET /orgs/{org}/teams/{team_slug}/members", "GET /orgs/{org}/teams/{team_slug}/projects", "GET /orgs/{org}/teams/{team_slug}/repos", "GET /orgs/{org}/teams/{team_slug}/teams", "GET /projects/columns/{column_id}/cards", "GET /projects/{project_id}/collaborators", "GET /projects/{project_id}/columns", "GET /repos/{owner}/{repo}/actions/artifacts", "GET /repos/{owner}/{repo}/actions/caches", "GET /repos/{owner}/{repo}/actions/runners", "GET /repos/{owner}/{repo}/actions/runs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs", "GET /repos/{owner}/{repo}/actions/secrets", "GET /repos/{owner}/{repo}/actions/workflows", "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs", "GET /repos/{owner}/{repo}/assignees", "GET /repos/{owner}/{repo}/branches", "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations", "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs", "GET /repos/{owner}/{repo}/code-scanning/alerts", "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", "GET /repos/{owner}/{repo}/code-scanning/analyses", "GET /repos/{owner}/{repo}/codespaces", "GET /repos/{owner}/{repo}/codespaces/devcontainers", "GET /repos/{owner}/{repo}/codespaces/secrets", "GET /repos/{owner}/{repo}/collaborators", "GET /repos/{owner}/{repo}/comments", "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/commits", "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments", "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls", "GET /repos/{owner}/{repo}/commits/{ref}/check-runs", "GET /repos/{owner}/{repo}/commits/{ref}/check-suites", "GET /repos/{owner}/{repo}/commits/{ref}/status", "GET /repos/{owner}/{repo}/commits/{ref}/statuses", "GET /repos/{owner}/{repo}/contributors", "GET /repos/{owner}/{repo}/dependabot/secrets", "GET /repos/{owner}/{repo}/deployments", "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses", "GET /repos/{owner}/{repo}/environments", "GET /repos/{owner}/{repo}/events", "GET /repos/{owner}/{repo}/forks", "GET /repos/{owner}/{repo}/git/matching-refs/{ref}", "GET /repos/{owner}/{repo}/hooks", "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", "GET /repos/{owner}/{repo}/invitations", "GET /repos/{owner}/{repo}/issues", "GET /repos/{owner}/{repo}/issues/comments", "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/issues/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/comments", "GET /repos/{owner}/{repo}/issues/{issue_number}/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/labels", "GET /repos/{owner}/{repo}/issues/{issue_number}/reactions", "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline", "GET /repos/{owner}/{repo}/keys", "GET /repos/{owner}/{repo}/labels", "GET /repos/{owner}/{repo}/milestones", "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels", "GET /repos/{owner}/{repo}/notifications", "GET /repos/{owner}/{repo}/pages/builds", "GET /repos/{owner}/{repo}/projects", "GET /repos/{owner}/{repo}/pulls", "GET /repos/{owner}/{repo}/pulls/comments", "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments", "GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", "GET /repos/{owner}/{repo}/pulls/{pull_number}/files", "GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments", "GET /repos/{owner}/{repo}/releases", "GET /repos/{owner}/{repo}/releases/{release_id}/assets", "GET /repos/{owner}/{repo}/releases/{release_id}/reactions", "GET /repos/{owner}/{repo}/secret-scanning/alerts", "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations", "GET /repos/{owner}/{repo}/stargazers", "GET /repos/{owner}/{repo}/subscribers", "GET /repos/{owner}/{repo}/tags", "GET /repos/{owner}/{repo}/teams", "GET /repos/{owner}/{repo}/topics", "GET /repositories", "GET /repositories/{repository_id}/environments/{environment_name}/secrets", "GET /search/code", "GET /search/commits", "GET /search/issues", "GET /search/labels", "GET /search/repositories", "GET /search/topics", "GET /search/users", "GET /teams/{team_id}/discussions", "GET /teams/{team_id}/discussions/{discussion_number}/comments", "GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /teams/{team_id}/discussions/{discussion_number}/reactions", "GET /teams/{team_id}/invitations", "GET /teams/{team_id}/members", "GET /teams/{team_id}/projects", "GET /teams/{team_id}/repos", "GET /teams/{team_id}/teams", "GET /user/blocks", "GET /user/codespaces", "GET /user/codespaces/secrets", "GET /user/emails", "GET /user/followers", "GET /user/following", "GET /user/gpg_keys", "GET /user/installations", "GET /user/installations/{installation_id}/repositories", "GET /user/issues", "GET /user/keys", "GET /user/marketplace_purchases", "GET /user/marketplace_purchases/stubbed", "GET /user/memberships/orgs", "GET /user/migrations", "GET /user/migrations/{migration_id}/repositories", "GET /user/orgs", "GET /user/packages", "GET /user/packages/{package_type}/{package_name}/versions", "GET /user/public_emails", "GET /user/repos", "GET /user/repository_invitations", "GET /user/starred", "GET /user/subscriptions", "GET /user/teams", "GET /users", "GET /users/{username}/events", "GET /users/{username}/events/orgs/{org}", "GET /users/{username}/events/public", "GET /users/{username}/followers", "GET /users/{username}/following", "GET /users/{username}/gists", "GET /users/{username}/gpg_keys", "GET /users/{username}/keys", "GET /users/{username}/orgs", "GET /users/{username}/packages", "GET /users/{username}/projects", "GET /users/{username}/received_events", "GET /users/{username}/received_events/public", "GET /users/{username}/repos", "GET /users/{username}/starred", "GET /users/{username}/subscriptions"]; +exports.request = request; +//# sourceMappingURL=index.js.map -function isPaginatingEndpoint(arg) { - if (typeof arg === "string") { - return paginatingEndpoints.includes(arg); - } else { - return false; - } -} -/** - * @param octokit Octokit instance - * @param options Options passed to Octokit constructor - */ +/***/ }), -function paginateRest(octokit) { - return { - paginate: Object.assign(paginate.bind(null, octokit), { - iterator: iterator.bind(null, octokit) - }) - }; -} -paginateRest.VERSION = VERSION; - -exports.composePaginateRest = composePaginateRest; -exports.isPaginatingEndpoint = isPaginatingEndpoint; -exports.paginateRest = paginateRest; -exports.paginatingEndpoints = paginatingEndpoints; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 7471: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 5526: +/***/ (function(__unused_webpack_module, exports) { "use strict"; - +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var deprecation = __nccwpck_require__(8932); -var once = _interopDefault(__nccwpck_require__(1223)); - -const logOnceCode = once(deprecation => console.warn(deprecation)); -const logOnceHeaders = once(deprecation => console.warn(deprecation)); -/** - * Error with extra properties to help with debugging - */ - -class RequestError extends Error { - constructor(message, statusCode, options) { - super(message); // Maintains proper stack trace (only available on V8) - - /* istanbul ignore next */ - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); +exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; +class BasicCredentialHandler { + constructor(username, password) { + this.username = username; + this.password = password; } - - this.name = "HttpError"; - this.status = statusCode; - let headers; - - if ("headers" in options && typeof options.headers !== "undefined") { - headers = options.headers; + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; } - - if ("response" in options) { - this.response = options.response; - headers = options.response.headers; - } // redact request credentials without mutating original request options - - - const requestCopy = Object.assign({}, options.request); - - if (options.request.headers.authorization) { - requestCopy.headers = Object.assign({}, options.request.headers, { - authorization: options.request.headers.authorization.replace(/ .*$/, " [REDACTED]") - }); + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); } - - requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit - // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications - .replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]") // OAuth tokens can be passed as URL query parameters, although it is not recommended - // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header - .replace(/\baccess_token=\w+/g, "access_token=[REDACTED]"); - this.request = requestCopy; // deprecations - - Object.defineProperty(this, "code", { - get() { - logOnceCode(new deprecation.Deprecation("[@octokit/request-error] `error.code` is deprecated, use `error.status`.")); - return statusCode; - } - - }); - Object.defineProperty(this, "headers", { - get() { - logOnceHeaders(new deprecation.Deprecation("[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`.")); - return headers || {}; - } - - }); - } - } - -exports.RequestError = RequestError; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9353: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var endpoint = __nccwpck_require__(8713); -var universalUserAgent = __nccwpck_require__(5030); -var isPlainObject = __nccwpck_require__(3287); -var nodeFetch = _interopDefault(__nccwpck_require__(467)); -var requestError = __nccwpck_require__(7471); - -const VERSION = "5.6.3"; - -function getBufferResponse(response) { - return response.arrayBuffer(); +exports.BasicCredentialHandler = BasicCredentialHandler; +class BearerCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Bearer ${this.token}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } } - -function fetchWrapper(requestOptions) { - const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console; - - if (isPlainObject.isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) { - requestOptions.body = JSON.stringify(requestOptions.body); - } - - let headers = {}; - let status; - let url; - const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch; - return fetch(requestOptions.url, Object.assign({ - method: requestOptions.method, - body: requestOptions.body, - headers: requestOptions.headers, - redirect: requestOptions.redirect - }, // `requestOptions.request.agent` type is incompatible - // see https://github.com/octokit/types.ts/pull/264 - requestOptions.request)).then(async response => { - url = response.url; - status = response.status; - - for (const keyAndValue of response.headers) { - headers[keyAndValue[0]] = keyAndValue[1]; +exports.BearerCredentialHandler = BearerCredentialHandler; +class PersonalAccessTokenCredentialHandler { + constructor(token) { + this.token = token; } - - if ("deprecation" in headers) { - const matches = headers.link && headers.link.match(/<([^>]+)>; rel="deprecation"/); - const deprecationLink = matches && matches.pop(); - log.warn(`[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}`); + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; } - - if (status === 204 || status === 205) { - return; - } // GitHub API returns 200 for HEAD requests - - - if (requestOptions.method === "HEAD") { - if (status < 400) { - return; - } - - throw new requestError.RequestError(response.statusText, status, { - response: { - url, - status, - headers, - data: undefined - }, - request: requestOptions - }); + // This handler cannot handle 401 + canHandleAuthentication() { + return false; } - - if (status === 304) { - throw new requestError.RequestError("Not modified", status, { - response: { - url, - status, - headers, - data: await getResponseData(response) - }, - request: requestOptions - }); + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); } +} +exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; +//# sourceMappingURL=auth.js.map - if (status >= 400) { - const data = await getResponseData(response); - const error = new requestError.RequestError(toErrorMessage(data), status, { - response: { - url, - status, - headers, - data - }, - request: requestOptions - }); - throw error; - } - - return getResponseData(response); - }).then(data => { - return { - status, - url, - headers, - data - }; - }).catch(error => { - if (error instanceof requestError.RequestError) throw error; - throw new requestError.RequestError(error.message, 500, { - request: requestOptions - }); - }); -} - -async function getResponseData(response) { - const contentType = response.headers.get("content-type"); - - if (/application\/json/.test(contentType)) { - return response.json(); - } - - if (!contentType || /^text\/|charset=utf-8$/.test(contentType)) { - return response.text(); - } - - return getBufferResponse(response); -} - -function toErrorMessage(data) { - if (typeof data === "string") return data; // istanbul ignore else - just in case - - if ("message" in data) { - if (Array.isArray(data.errors)) { - return `${data.message}: ${data.errors.map(JSON.stringify).join(", ")}`; - } - - return data.message; - } // istanbul ignore next - just in case - - - return `Unknown error: ${JSON.stringify(data)}`; -} - -function withDefaults(oldEndpoint, newDefaults) { - const endpoint = oldEndpoint.defaults(newDefaults); - - const newApi = function (route, parameters) { - const endpointOptions = endpoint.merge(route, parameters); - - if (!endpointOptions.request || !endpointOptions.request.hook) { - return fetchWrapper(endpoint.parse(endpointOptions)); - } - - const request = (route, parameters) => { - return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters))); - }; - - Object.assign(request, { - endpoint, - defaults: withDefaults.bind(null, endpoint) - }); - return endpointOptions.request.hook(request, endpointOptions); - }; - - return Object.assign(newApi, { - endpoint, - defaults: withDefaults.bind(null, endpoint) - }); -} - -const request = withDefaults(endpoint.endpoint, { - headers: { - "user-agent": `octokit-request.js/${VERSION} ${universalUserAgent.getUserAgent()}` - } -}); - -exports.request = request; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 5526: -/***/ (function(__unused_webpack_module, exports) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; -class BasicCredentialHandler { - constructor(username, password) { - this.username = username; - this.password = password; - } - prepareRequest(options) { - if (!options.headers) { - throw Error('The request has no headers'); - } - options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; - } - // This handler cannot handle 401 - canHandleAuthentication() { - return false; - } - handleAuthentication() { - return __awaiter(this, void 0, void 0, function* () { - throw new Error('not implemented'); - }); - } -} -exports.BasicCredentialHandler = BasicCredentialHandler; -class BearerCredentialHandler { - constructor(token) { - this.token = token; - } - // currently implements pre-authorization - // TODO: support preAuth = false where it hooks on 401 - prepareRequest(options) { - if (!options.headers) { - throw Error('The request has no headers'); - } - options.headers['Authorization'] = `Bearer ${this.token}`; - } - // This handler cannot handle 401 - canHandleAuthentication() { - return false; - } - handleAuthentication() { - return __awaiter(this, void 0, void 0, function* () { - throw new Error('not implemented'); - }); - } -} -exports.BearerCredentialHandler = BearerCredentialHandler; -class PersonalAccessTokenCredentialHandler { - constructor(token) { - this.token = token; - } - // currently implements pre-authorization - // TODO: support preAuth = false where it hooks on 401 - prepareRequest(options) { - if (!options.headers) { - throw Error('The request has no headers'); - } - options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; - } - // This handler cannot handle 401 - canHandleAuthentication() { - return false; - } - handleAuthentication() { - return __awaiter(this, void 0, void 0, function* () { - throw new Error('not implemented'); - }); - } -} -exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; -//# sourceMappingURL=auth.js.map - -/***/ }), +/***/ }), /***/ 6255: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { @@ -7404,4152 +6858,2542 @@ exports.isPlainObject = isPlainObject; /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; - - -/***/ }), - -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), - -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); +/***/ 467: +/***/ ((module, exports, __nccwpck_require__) => { -module.exports = Map; +"use strict"; -/***/ }), +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +var Stream = _interopDefault(__nccwpck_require__(2781)); +var http = _interopDefault(__nccwpck_require__(3685)); +var Url = _interopDefault(__nccwpck_require__(7310)); +var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); +var https = _interopDefault(__nccwpck_require__(5687)); +var zlib = _interopDefault(__nccwpck_require__(9796)); -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; -module.exports = MapCache; +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); +class Blob { + constructor() { + this[TYPE] = ''; -/***/ }), + const blobParts = arguments[0]; + const options = arguments[1]; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const buffers = []; + let size = 0; -var root = __nccwpck_require__(9882); + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } -/** Built-in value references. */ -var Symbol = root.Symbol; + this[BUFFER] = Buffer.concat(buffers); -module.exports = Symbol; - - -/***/ }), - -/***/ 4356: -/***/ ((module) => { + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } } -module.exports = arrayMap; - - -/***/ }), - -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); -var eq = __nccwpck_require__(1901); +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); /** - * Gets the index at which the `key` is found in `array` of key-value pairs. + * fetch-error.js * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. + * FetchError interface for operational errors */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -module.exports = assocIndexOf; - - -/***/ }), - -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); /** - * The base implementation of `_.get` without support for default values. + * Create FetchError instance * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError */ -function baseGet(object, path) { - path = castPath(path, object); +function FetchError(message, type, systemError) { + Error.call(this, message); - var index = 0, - length = path.length; + this.message = message; + this.type = type; - while (object != null && index < length) { - object = object[toKey(path[index++])]; + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; } - return (index && index == length) ? object : undefined; -} - -module.exports = baseGet; + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); +let convert; +try { + convert = (__nccwpck_require__(2877).convert); +} catch (e) {} -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; +const INTERNALS = Symbol('Body internals'); -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; /** - * The base implementation of `getTag` without fallbacks for buggy environments. + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} - -module.exports = baseGetTag; +function Body(body) { + var _this = this; + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; -/***/ }), + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; + get bodyUsed() { + return this[INTERNALS].disturbed; + }, -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, -module.exports = baseIsNative; + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; -/***/ }), - -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. + * Consume and convert an entire Body to a Buffer. * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = baseToString; - - -/***/ }), - -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); - -/** - * Casts `value` to a path array if it's not one. + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. + * @return Promise */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function consumeBody() { + var _this4 = this; -var root = __nccwpck_require__(9882); + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + this[INTERNALS].disturbed = true; -module.exports = coreJsData; + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + let body = this.body; -/***/ }), + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -/***/ 2085: -/***/ ((module) => { + // body is blob + if (isBlob(body)) { + body = body.stream(); + } -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } -module.exports = freeGlobal; + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; -/***/ }), + return new Body.Promise(function (resolve, reject) { + let resTimeout; -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } -var isKeyable = __nccwpck_require__(3308); + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } -module.exports = getMapData; + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + accumBytes += chunk.length; + accum.push(chunk); + }); -/***/ }), + body.on('end', function () { + if (abort) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + clearTimeout(resTimeout); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} /** - * Gets the native function at `key` of `object`. + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -module.exports = getNative; +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; -/***/ }), + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); -var Symbol = __nccwpck_require__(9213); + // html5 + if (!res && str) { + res = / { - /** - * Gets the value at `key` of `object`. + * Detect a URLSearchParams object + * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. + * @param Object obj Object to detect by type or brand + * @return String */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -module.exports = getValue; - - -/***/ }), - -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function isURLSearchParams(obj) { + // Duck-typing as a necessary condition. + if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { + return false; + } -var nativeCreate = __nccwpck_require__(3041); + // Brand-checking and more duck-typing as optional condition. + return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; +} /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash + * Check if `obj` is a W3C `Blob` object (which `File` inherits from) + * @param {*} obj + * @return {boolean} */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; +function isBlob(obj) { + return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); } -module.exports = hashClear; - - -/***/ }), - -/***/ 712: -/***/ ((module) => { - /** - * Removes `key` and its value from the hash. + * Clone body given Res/Req instance * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @param Mixed instance Response or Request instance + * @return Mixed */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} - -module.exports = hashDelete; +function clone(instance) { + let p1, p2; + let body = instance.body; + // don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } -/***/ }), - -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof Stream && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + return body; +} /** - * Gets the hash value for `key`. + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract + * + * This function assumes that instance.body is present. * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @param Mixed instance Any options.body input */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof Stream) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } } -module.exports = hashGet; - - -/***/ }), - -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - /** - * Checks if a hash value for `key` exists. + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), - -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getTotalBytes(instance) { + const body = instance.body; -var nativeCreate = __nccwpck_require__(3041); -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} /** - * Sets the hash `key` to `value`. + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. + * @param Body instance Instance of Body + * @return Void */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -module.exports = hashSet; - - -/***/ }), +function writeToStream(dest, instance) { + const body = instance.body; -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } +} -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; +// expose Promise +Body.Promise = global.Promise; /** - * Checks if `value` is a property name and not a property path. + * headers.js * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + * Headers class offers convenient helpers */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} - -module.exports = isKey; +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; -/***/ }), +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } +} -/***/ 3308: -/***/ ((module) => { +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } +} /** - * Checks if `value` is suitable for use as unique object key. + * Find the key in the map object given a header name. + * + * Returns undefined if not found. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + * @param String name Header name + * @return String|Undefined */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; } -module.exports = isKeyable; +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + this[MAP] = Object.create(null); -/***/ }), + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } -var coreJsData = __nccwpck_require__(8380); + return; + } -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } -module.exports = isMasked; + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } -/***/ }), + return this[MAP][key].join(', '); + } -/***/ 9792: -/***/ ((module) => { + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; -module.exports = listCacheClear; + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } -/***/ }), + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } -var assocIndexOf = __nccwpck_require__(6752); + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } -/** Built-in value references. */ -var splice = arrayProto.splice; + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } } +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -module.exports = listCacheDelete; - +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); -/***/ }), +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; -var assocIndexOf = __nccwpck_require__(6752); + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); +const INTERNAL = Symbol('internal'); - return index < 0 ? undefined : data[index][1]; +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; } -module.exports = listCacheGet; +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; -/***/ }), + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); -var assocIndexOf = __nccwpck_require__(6752); +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); /** - * Checks if a list cache value for `key` exists. + * Export the Headers object in a form that Node.js can consume. * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param Headers headers + * @return Object */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -module.exports = listCacheHas; - - -/***/ }), +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } -var assocIndexOf = __nccwpck_require__(6752); + return obj; +} /** - * Sets the list cache `key` to `value`. + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. + * @param Object obj Object of headers + * @return Headers */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; } -module.exports = listCacheSet; - - -/***/ }), - -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$1 = Symbol('Response internals'); -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; /** - * Removes all key-value entries from the map. + * Response class * - * @private - * @name clear - * @memberOf MapCache + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Body.call(this, body, opts); -/***/ }), + const status = opts.status || 200; + const headers = new Headers(opts.headers); -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -var getMapData = __nccwpck_require__(9980); + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + get url() { + return this[INTERNALS$1].url || ''; + } -module.exports = mapCacheDelete; + get status() { + return this[INTERNALS$1].status; + } + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } -/***/ }), + get redirected() { + return this[INTERNALS$1].counter > 0; + } -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + get statusText() { + return this[INTERNALS$1].statusText; + } -var getMapData = __nccwpck_require__(9980); + get headers() { + return this[INTERNALS$1].headers; + } -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } } -module.exports = mapCacheGet; +Body.mixIn(Response.prototype); +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); -/***/ }), +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; -var getMapData = __nccwpck_require__(9980); +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; /** - * Checks if a map value for `key` exists. + * Wrapper around `new URL` to handle arbitrary URLs * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param {string} urlStr + * @return {void} */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -module.exports = mapCacheHas; - - -/***/ }), +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} -var getMapData = __nccwpck_require__(9980); +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; /** - * Sets the map `key` to `value`. + * Check if a value is an instance of Request. * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. + * @param Mixed input + * @return Boolean */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; - - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; } -module.exports = mapCacheSet; - - -/***/ }), - -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var memoize = __nccwpck_require__(9885); - -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * Request class * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); - - var cache = result.cache; - return result; -} - -module.exports = memoizeCapped; - - -/***/ }), - -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479); - -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; -module.exports = nativeCreate; + let parsedURL; + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } -/***/ }), + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); -/***/ 4200: -/***/ ((module) => { + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + const headers = new Headers(init.headers || input.headers || {}); -module.exports = objectToString; + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; -/***/ }), + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; -var freeGlobal = __nccwpck_require__(2085); + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + get method() { + return this[INTERNALS$2].method; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } -module.exports = root; + get headers() { + return this[INTERNALS$2].headers; + } + get redirect() { + return this[INTERNALS$2].redirect; + } -/***/ }), + get signal() { + return this[INTERNALS$2].signal; + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} -var memoizeCapped = __nccwpck_require__(9422); +Body.mixIn(Request.prototype); -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); /** - * Converts `string` to a property path array. + * Convert a Request to Node.js http request options. * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. + * @param Request A Request instance + * @return Object The options object to be passed to http.request */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); - -module.exports = stringToPath; - - -/***/ }), +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } -var isSymbol = __nccwpck_require__(6403); + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } -module.exports = toKey; + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } -/***/ }), + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } -/***/ 6928: -/***/ ((module) => { + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); } -module.exports = toSource; - - -/***/ }), - -/***/ 1901: -/***/ ((module) => { - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false + * abort-error.js * - * _.eq(NaN, NaN); - * // => true + * AbortError interface for cancelled requests */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -module.exports = eq; - - -/***/ }), - -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseGet = __nccwpck_require__(5758); /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 + * Create AbortError instance * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' + * @param String message Error message for human + * @return AbortError */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} - -module.exports = get; - - -/***/ }), - -/***/ 4869: -/***/ ((module) => { +function AbortError(message) { + Error.call(this, message); -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + this.type = 'aborted'; + this.message = message; -module.exports = isArray; + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; -/***/ }), +const URL$1 = Url.URL || whatwgUrl.URL; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true + * Fetch function * - * _.isFunction(/abc/); - * // => false + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} - -module.exports = isFunction; +function fetch(url, opts) { + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } -/***/ }), + Body.Promise = fetch.Promise; -/***/ 3334: -/***/ ((module) => { + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; -module.exports = isObject; + let response = null; + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + request.body.destroy(error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; -/***/ }), + if (signal && signal.aborted) { + abort(); + return; + } -/***/ 5926: -/***/ ((module) => { + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} + // send request + const req = send(options); + let reqTimeout; -module.exports = isObjectLike; + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } -/***/ }), + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + finalize(); + }); -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + req.on('response', function (res) { + clearTimeout(reqTimeout); -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + const headers = createHeadersLenient(res.headers); -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); -module.exports = isSymbol; + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } -/***/ }), + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; -var MapCache = __nccwpck_require__(938); + if (!isDomainOrSubdomain(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; -// Expose `MapCache`. -memoize.Cache = MapCache; + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); -module.exports = memoize; + // HTTP-network fetch step 12.1.1.4: handle content codings + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } -/***/ }), + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } -var baseToString = __nccwpck_require__(6792); + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + writeToStream(req, request); + }); +} /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' + * Redirect code matching * - * _.toString([1, 2, 3]); - * // => '1,2,3' + * @param Number code Status code + * @return Boolean */ -function toString(value) { - return value == null ? '' : baseToString(value); -} +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; -module.exports = toString; +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports["default"] = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; /***/ }), -/***/ 467: -/***/ ((module, exports, __nccwpck_require__) => { +/***/ 2299: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); +var punycode = __nccwpck_require__(5477); +var mappingTable = __nccwpck_require__(1907); -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } +var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 +}; -var Stream = _interopDefault(__nccwpck_require__(2781)); -var http = _interopDefault(__nccwpck_require__(3685)); -var Url = _interopDefault(__nccwpck_require__(7310)); -var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); -var https = _interopDefault(__nccwpck_require__(5687)); -var zlib = _interopDefault(__nccwpck_require__(9796)); +function normalize(str) { // fix bug in v8 + return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); +} -// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js +function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; -// fix for "Readable" isn't a named export issue -const Readable = Stream.Readable; + while (start <= end) { + var mid = Math.floor((start + end) / 2); -const BUFFER = Symbol('buffer'); -const TYPE = Symbol('type'); + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } -class Blob { - constructor() { - this[TYPE] = ''; + return null; +} - const blobParts = arguments[0]; - const options = arguments[1]; +var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; - const buffers = []; - let size = 0; +function countSymbols(string) { + return string + // replace every surrogate pair with a BMP symbol + .replace(regexAstralSymbols, '_') + // then get the length + .length; +} - if (blobParts) { - const a = blobParts; - const length = Number(a.length); - for (let i = 0; i < length; i++) { - const element = a[i]; - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = element[BUFFER]; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); - } - size += buffer.length; - buffers.push(buffer); - } - } +function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; - this[BUFFER] = Buffer.concat(buffers); + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); - let type = options && options.type !== undefined && String(options.type).toLowerCase(); - if (type && !/[^\u0020-\u007E]/.test(type)) { - this[TYPE] = type; - } - } - get size() { - return this[BUFFER].length; - } - get type() { - return this[TYPE]; - } - text() { - return Promise.resolve(this[BUFFER].toString()); - } - arrayBuffer() { - const buf = this[BUFFER]; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); - } - stream() { - const readable = new Readable(); - readable._read = function () {}; - readable.push(this[BUFFER]); - readable.push(null); - return readable; - } - toString() { - return '[object Blob]'; - } - slice() { - const size = this.size; + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } - const start = arguments[0]; - const end = arguments[1]; - let relativeStart, relativeEnd; - if (start === undefined) { - relativeStart = 0; - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); - } else { - relativeStart = Math.min(start, size); - } - if (end === undefined) { - relativeEnd = size; - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); - } else { - relativeEnd = Math.min(end, size); - } - const span = Math.max(relativeEnd - relativeStart, 0); + processed += String.fromCodePoint(codePoint); + break; + } + } - const buffer = this[BUFFER]; - const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); - const blob = new Blob([], { type: arguments[2] }); - blob[BUFFER] = slicedBuffer; - return blob; - } + return { + string: processed, + error: hasError + }; } -Object.defineProperties(Blob.prototype, { - size: { enumerable: true }, - type: { enumerable: true }, - slice: { enumerable: true } -}); +var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); +function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } -/** - * fetch-error.js - * - * FetchError interface for operational errors - */ + var error = false; -/** - * Create FetchError instance - * - * @param String message Error message for human - * @param String type Error type for machine - * @param String systemError For Node.js system error - * @return FetchError - */ -function FetchError(message, type, systemError) { - Error.call(this, message); + if (normalize(label) !== label || + (label[3] === "-" && label[4] === "-") || + label[0] === "-" || label[label.length - 1] === "-" || + label.indexOf(".") !== -1 || + label.search(combiningMarksRegex) === 0) { + error = true; + } - this.message = message; - this.type = type; + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || + (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && + status[1] !== "valid" && status[1] !== "deviation")) { + error = true; + break; + } + } - // when err.type is `system`, err.code contains system error code - if (systemError) { - this.code = this.errno = systemError.code; + return { + label: label, + error: error + }; +} + +function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); + + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch(e) { + result.error = true; + } } - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); + return { + string: labels.join("."), + error: result.error + }; } -FetchError.prototype = Object.create(Error.prototype); -FetchError.prototype.constructor = FetchError; -FetchError.prototype.name = 'FetchError'; +module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch(e) { + result.error = true; + return l; + } + }); -let convert; -try { - convert = (__nccwpck_require__(2877).convert); -} catch (e) {} + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } -const INTERNALS = Symbol('Body internals'); + for (var i=0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } -// fix an issue where "PassThrough" isn't a named export for node <10 -const PassThrough = Stream.PassThrough; + if (result.error) return null; + return labels.join("."); +}; -/** - * Body mixin - * - * Ref: https://fetch.spec.whatwg.org/#body - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -function Body(body) { - var _this = this; +module.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref$size = _ref.size; + return { + domain: result.string, + error: result.error + }; +}; - let size = _ref$size === undefined ? 0 : _ref$size; - var _ref$timeout = _ref.timeout; - let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; +module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - if (body == null) { - // body is undefined or null - body = null; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - body = Buffer.from(body.toString()); - } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - body = Buffer.from(body); - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); - } else if (body instanceof Stream) ; else { - // none of the above - // coerce to string then buffer - body = Buffer.from(String(body)); - } - this[INTERNALS] = { - body, - disturbed: false, - error: null - }; - this.size = size; - this.timeout = timeout; - if (body instanceof Stream) { - body.on('error', function (err) { - const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); - _this[INTERNALS].error = error; - }); - } -} +/***/ }), -Body.prototype = { - get body() { - return this[INTERNALS].body; - }, +/***/ 5871: +/***/ ((module) => { - get bodyUsed() { - return this[INTERNALS].disturbed; - }, +"use strict"; - /** - * Decode response as ArrayBuffer - * - * @return Promise - */ - arrayBuffer() { - return consumeBody.call(this).then(function (buf) { - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - }); - }, - /** - * Return raw response as Blob - * - * @return Promise - */ - blob() { - let ct = this.headers && this.headers.get('content-type') || ''; - return consumeBody.call(this).then(function (buf) { - return Object.assign( - // Prevent copying - new Blob([], { - type: ct.toLowerCase() - }), { - [BUFFER]: buf - }); - }); - }, +var conversions = {}; +module.exports = conversions; - /** - * Decode response as json - * - * @return Promise - */ - json() { - var _this2 = this; +function sign(x) { + return x < 0 ? -1 : 1; +} - return consumeBody.call(this).then(function (buffer) { - try { - return JSON.parse(buffer.toString()); - } catch (err) { - return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); - } - }); - }, +function evenRound(x) { + // Round x to the nearest integer, choosing the even integer if it lies halfway between two. + if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) + return Math.floor(x); + } else { + return Math.round(x); + } +} - /** - * Decode response as text - * - * @return Promise - */ - text() { - return consumeBody.call(this).then(function (buffer) { - return buffer.toString(); - }); - }, +function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength; + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); + const upperBound = Math.pow(2, bitLength) - 1; - /** - * Decode response as buffer (non-spec api) - * - * @return Promise - */ - buffer() { - return consumeBody.call(this); - }, + const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); + const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - /** - * Decode response as text, while automatically detecting the encoding and - * trying to decode to UTF-8 (non-spec api) - * - * @return Promise - */ - textConverted() { - var _this3 = this; + return function(V, opts) { + if (!opts) opts = {}; - return consumeBody.call(this).then(function (buffer) { - return convertBody(buffer, _this3.headers); - }); - } -}; + let x = +V; -// In browsers, all properties are enumerable. -Object.defineProperties(Body.prototype, { - body: { enumerable: true }, - bodyUsed: { enumerable: true }, - arrayBuffer: { enumerable: true }, - blob: { enumerable: true }, - json: { enumerable: true }, - text: { enumerable: true } -}); + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite number"); + } -Body.mixIn = function (proto) { - for (const name of Object.getOwnPropertyNames(Body.prototype)) { - // istanbul ignore else: future proof - if (!(name in proto)) { - const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); - Object.defineProperty(proto, name, desc); - } - } -}; + x = sign(x) * Math.floor(Math.abs(x)); + if (x < lowerBound || x > upperBound) { + throw new TypeError("Argument is not in byte range"); + } -/** - * Consume and convert an entire Body to a Buffer. - * - * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body - * - * @return Promise - */ -function consumeBody() { - var _this4 = this; + return x; + } - if (this[INTERNALS].disturbed) { - return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); - } + if (!isNaN(x) && opts.clamp) { + x = evenRound(x); - this[INTERNALS].disturbed = true; + if (x < lowerBound) x = lowerBound; + if (x > upperBound) x = upperBound; + return x; + } - if (this[INTERNALS].error) { - return Body.Promise.reject(this[INTERNALS].error); - } + if (!Number.isFinite(x) || x === 0) { + return 0; + } - let body = this.body; + x = sign(x) * Math.floor(Math.abs(x)); + x = x % moduloVal; - // body is null - if (body === null) { - return Body.Promise.resolve(Buffer.alloc(0)); - } + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal; + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal; + } else if (x === -0) { // don't return negative zero + return 0; + } + } - // body is blob - if (isBlob(body)) { - body = body.stream(); - } + return x; + } +} - // body is buffer - if (Buffer.isBuffer(body)) { - return Body.Promise.resolve(body); - } +conversions["void"] = function () { + return undefined; +}; - // istanbul ignore if: should never happen - if (!(body instanceof Stream)) { - return Body.Promise.resolve(Buffer.alloc(0)); - } +conversions["boolean"] = function (val) { + return !!val; +}; - // body is stream - // get ready to actually consume the body - let accum = []; - let accumBytes = 0; - let abort = false; +conversions["byte"] = createNumberConversion(8, { unsigned: false }); +conversions["octet"] = createNumberConversion(8, { unsigned: true }); - return new Body.Promise(function (resolve, reject) { - let resTimeout; +conversions["short"] = createNumberConversion(16, { unsigned: false }); +conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - // allow timeout on slow response body - if (_this4.timeout) { - resTimeout = setTimeout(function () { - abort = true; - reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); - }, _this4.timeout); - } +conversions["long"] = createNumberConversion(32, { unsigned: false }); +conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - // handle stream errors - body.on('error', function (err) { - if (err.name === 'AbortError') { - // if the request was aborted, reject with this Error - abort = true; - reject(err); - } else { - // other errors, such as incorrect content-encoding - reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); - } - }); +conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); +conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - body.on('data', function (chunk) { - if (abort || chunk === null) { - return; - } +conversions["double"] = function (V) { + const x = +V; - if (_this4.size && accumBytes + chunk.length > _this4.size) { - abort = true; - reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); - return; - } + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite floating-point value"); + } - accumBytes += chunk.length; - accum.push(chunk); - }); + return x; +}; - body.on('end', function () { - if (abort) { - return; - } +conversions["unrestricted double"] = function (V) { + const x = +V; - clearTimeout(resTimeout); + if (isNaN(x)) { + throw new TypeError("Argument is NaN"); + } - try { - resolve(Buffer.concat(accum, accumBytes)); - } catch (err) { - // handle streams that have accumulated too much data (issue #414) - reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - }); -} + return x; +}; -/** - * Detect buffer encoding and convert to target encoding - * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding - * - * @param Buffer buffer Incoming buffer - * @param String encoding Target encoding - * @return String - */ -function convertBody(buffer, headers) { - if (typeof convert !== 'function') { - throw new Error('The package `encoding` must be installed to use the textConverted() function'); - } +// not quite valid, but good enough for JS +conversions["float"] = conversions["double"]; +conversions["unrestricted float"] = conversions["unrestricted double"]; - const ct = headers.get('content-type'); - let charset = 'utf-8'; - let res, str; +conversions["DOMString"] = function (V, opts) { + if (!opts) opts = {}; - // header - if (ct) { - res = /charset=([^;]*)/i.exec(ct); - } + if (opts.treatNullAsEmptyString && V === null) { + return ""; + } - // no charset in content type, peek at response body for at most 1024 bytes - str = buffer.slice(0, 1024).toString(); + return String(V); +}; - // html5 - if (!res && str) { - res = / 255) { + throw new TypeError("Argument is not a valid bytestring"); + } + } - // html4 - if (!res && str) { - res = / 0xDFFF) { + U.push(String.fromCodePoint(c)); + } else if (0xDC00 <= c && c <= 0xDFFF) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + const d = S.charCodeAt(i + 1); + if (0xDC00 <= d && d <= 0xDFFF) { + const a = c & 0x3FF; + const b = d & 0x3FF; + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); + ++i; + } else { + U.push(String.fromCodePoint(0xFFFD)); + } + } + } + } - // xml - if (!res && str) { - res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); - } + return U.join(''); +}; - // found charset - if (res) { - charset = res.pop(); +conversions["Date"] = function (V, opts) { + if (!(V instanceof Date)) { + throw new TypeError("Argument is not a Date object"); + } + if (isNaN(V)) { + return undefined; + } - // prevent decode issues when sites use incorrect encoding - // ref: https://hsivonen.fi/encoding-menu/ - if (charset === 'gb2312' || charset === 'gbk') { - charset = 'gb18030'; - } - } + return V; +}; - // turn raw buffers into a single utf-8 buffer - return convert(buffer, 'UTF-8', charset).toString(); -} +conversions["RegExp"] = function (V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V); + } -/** - * Detect a URLSearchParams object - * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 - * - * @param Object obj Object to detect by type or brand - * @return String - */ -function isURLSearchParams(obj) { - // Duck-typing as a necessary condition. - if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { - return false; - } + return V; +}; - // Brand-checking and more duck-typing as optional condition. - return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; -} -/** - * Check if `obj` is a W3C `Blob` object (which `File` inherits from) - * @param {*} obj - * @return {boolean} - */ -function isBlob(obj) { - return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); -} +/***/ }), -/** - * Clone body given Res/Req instance - * - * @param Mixed instance Response or Request instance - * @return Mixed - */ -function clone(instance) { - let p1, p2; - let body = instance.body; +/***/ 8262: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // don't allow cloning a used body - if (instance.bodyUsed) { - throw new Error('cannot clone body after it is used'); - } +"use strict"; - // check that body is a stream and not form-data object - // note: we can't clone the form-data object without having it as a dependency - if (body instanceof Stream && typeof body.getBoundary !== 'function') { - // tee instance body - p1 = new PassThrough(); - p2 = new PassThrough(); - body.pipe(p1); - body.pipe(p2); - // set instance body to teed body and return the other teed body - instance[INTERNALS].body = p1; - body = p2; - } +const usm = __nccwpck_require__(33); - return body; -} +exports.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0]; + const base = constructorArgs[1]; -/** - * Performs the operation "extract a `Content-Type` value from |object|" as - * specified in the specification: - * https://fetch.spec.whatwg.org/#concept-bodyinit-extract - * - * This function assumes that instance.body is present. - * - * @param Mixed instance Any options.body input - */ -function extractContentType(body) { - if (body === null) { - // body is null - return null; - } else if (typeof body === 'string') { - // body is string - return 'text/plain;charset=UTF-8'; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - return 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isBlob(body)) { - // body is blob - return body.type || null; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return null; - } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - return null; - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - return null; - } else if (typeof body.getBoundary === 'function') { - // detect form data input from form-data module - return `multipart/form-data;boundary=${body.getBoundary()}`; - } else if (body instanceof Stream) { - // body is stream - // can't really do much about this - return null; - } else { - // Body constructor defaults other things to string - return 'text/plain;charset=UTF-8'; - } -} + let parsedBase = null; + if (base !== undefined) { + parsedBase = usm.basicURLParse(base); + if (parsedBase === "failure") { + throw new TypeError("Invalid base URL"); + } + } -/** - * The Fetch Standard treats this as if "total bytes" is a property on the body. - * For us, we have to explicitly get it with a function. - * - * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes - * - * @param Body instance Instance of Body - * @return Number? Number of bytes, or null if not possible - */ -function getTotalBytes(instance) { - const body = instance.body; + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } + this._url = parsedURL; - if (body === null) { - // body is null - return 0; - } else if (isBlob(body)) { - return body.size; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return body.length; - } else if (body && typeof body.getLengthSync === 'function') { - // detect form data input from form-data module - if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x - body.hasKnownLength && body.hasKnownLength()) { - // 2.x - return body.getLengthSync(); - } - return null; - } else { - // body is stream - return null; - } -} + // TODO: query stuff + } -/** - * Write a Body to a Node.js WritableStream (e.g. http.Request) object. - * - * @param Body instance Instance of Body - * @return Void - */ -function writeToStream(dest, instance) { - const body = instance.body; + get href() { + return usm.serializeURL(this._url); + } + set href(v) { + const parsedURL = usm.basicURLParse(v); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } - if (body === null) { - // body is null - dest.end(); - } else if (isBlob(body)) { - body.stream().pipe(dest); - } else if (Buffer.isBuffer(body)) { - // body is buffer - dest.write(body); - dest.end(); - } else { - // body is stream - body.pipe(dest); - } -} + this._url = parsedURL; + } -// expose Promise -Body.Promise = global.Promise; + get origin() { + return usm.serializeURLOrigin(this._url); + } -/** - * headers.js - * - * Headers class offers convenient helpers - */ + get protocol() { + return this._url.scheme + ":"; + } -const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; + set protocol(v) { + usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); + } -function validateName(name) { - name = `${name}`; - if (invalidTokenRegex.test(name) || name === '') { - throw new TypeError(`${name} is not a legal HTTP header name`); - } -} + get username() { + return this._url.username; + } -function validateValue(value) { - value = `${value}`; - if (invalidHeaderCharRegex.test(value)) { - throw new TypeError(`${value} is not a legal HTTP header value`); - } -} + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } -/** - * Find the key in the map object given a header name. - * - * Returns undefined if not found. - * - * @param String name Header name - * @return String|Undefined - */ -function find(map, name) { - name = name.toLowerCase(); - for (const key in map) { - if (key.toLowerCase() === name) { - return key; - } - } - return undefined; -} + usm.setTheUsername(this._url, v); + } -const MAP = Symbol('map'); -class Headers { - /** - * Headers class - * - * @param Object headers Response headers - * @return Void - */ - constructor() { - let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + get password() { + return this._url.password; + } - this[MAP] = Object.create(null); + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - if (init instanceof Headers) { - const rawHeaders = init.raw(); - const headerNames = Object.keys(rawHeaders); + usm.setThePassword(this._url, v); + } - for (const headerName of headerNames) { - for (const value of rawHeaders[headerName]) { - this.append(headerName, value); - } - } + get host() { + const url = this._url; - return; - } + if (url.host === null) { + return ""; + } - // We don't worry about converting prop to ByteString here as append() - // will handle it. - if (init == null) ; else if (typeof init === 'object') { - const method = init[Symbol.iterator]; - if (method != null) { - if (typeof method !== 'function') { - throw new TypeError('Header pairs must be iterable'); - } + if (url.port === null) { + return usm.serializeHost(url.host); + } - // sequence> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { - throw new TypeError('Each header pair must be iterable'); - } - pairs.push(Array.from(pair)); - } + return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); + } - for (const pair of pairs) { - if (pair.length !== 2) { - throw new TypeError('Each header pair must be a name/value tuple'); - } - this.append(pair[0], pair[1]); - } - } else { - // record - for (const key of Object.keys(init)) { - const value = init[key]; - this.append(key, value); - } - } - } else { - throw new TypeError('Provided initializer must be an object'); - } - } + set host(v) { + if (this._url.cannotBeABaseURL) { + return; + } - /** - * Return combined header value given name - * - * @param String name Header name - * @return Mixed - */ - get(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key === undefined) { - return null; - } + usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); + } - return this[MAP][key].join(', '); - } + get hostname() { + if (this._url.host === null) { + return ""; + } - /** - * Iterate over all headers - * - * @param Function callback Executed for each item with parameters (value, name, thisArg) - * @param Boolean thisArg `this` context for callback function - * @return Void - */ - forEach(callback) { - let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + return usm.serializeHost(this._url.host); + } - let pairs = getHeaders(this); - let i = 0; - while (i < pairs.length) { - var _pairs$i = pairs[i]; - const name = _pairs$i[0], - value = _pairs$i[1]; + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return; + } - callback.call(thisArg, value, name, this); - pairs = getHeaders(this); - i++; - } - } + usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); + } - /** - * Overwrite header values given name - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - set(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - this[MAP][key !== undefined ? key : name] = [value]; - } + get port() { + if (this._url.port === null) { + return ""; + } - /** - * Append a value onto existing header - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - append(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - if (key !== undefined) { - this[MAP][key].push(value); - } else { - this[MAP][name] = [value]; - } - } + return usm.serializeInteger(this._url.port); + } - /** - * Check for header name existence - * - * @param String name Header name - * @return Boolean - */ - has(name) { - name = `${name}`; - validateName(name); - return find(this[MAP], name) !== undefined; - } + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - /** - * Delete all header values given name - * - * @param String name Header name - * @return Void - */ - delete(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key !== undefined) { - delete this[MAP][key]; - } - } + if (v === "") { + this._url.port = null; + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); + } + } - /** - * Return raw headers (non-spec api) - * - * @return Object - */ - raw() { - return this[MAP]; - } + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0]; + } - /** - * Get an iterator on keys. - * - * @return Iterator - */ - keys() { - return createHeadersIterator(this, 'key'); - } + if (this._url.path.length === 0) { + return ""; + } - /** - * Get an iterator on values. - * - * @return Iterator - */ - values() { - return createHeadersIterator(this, 'value'); - } + return "/" + this._url.path.join("/"); + } - /** - * Get an iterator on entries. - * - * This is the default iterator of the Headers object. - * - * @return Iterator - */ - [Symbol.iterator]() { - return createHeadersIterator(this, 'key+value'); - } -} -Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return; + } -Object.defineProperty(Headers.prototype, Symbol.toStringTag, { - value: 'Headers', - writable: false, - enumerable: false, - configurable: true -}); + this._url.path = []; + usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); + } -Object.defineProperties(Headers.prototype, { - get: { enumerable: true }, - forEach: { enumerable: true }, - set: { enumerable: true }, - append: { enumerable: true }, - has: { enumerable: true }, - delete: { enumerable: true }, - keys: { enumerable: true }, - values: { enumerable: true }, - entries: { enumerable: true } -}); + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } -function getHeaders(headers) { - let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + return "?" + this._url.query; + } - const keys = Object.keys(headers[MAP]).sort(); - return keys.map(kind === 'key' ? function (k) { - return k.toLowerCase(); - } : kind === 'value' ? function (k) { - return headers[MAP][k].join(', '); - } : function (k) { - return [k.toLowerCase(), headers[MAP][k].join(', ')]; - }); -} + set search(v) { + // TODO: query stuff -const INTERNAL = Symbol('internal'); + const url = this._url; -function createHeadersIterator(target, kind) { - const iterator = Object.create(HeadersIteratorPrototype); - iterator[INTERNAL] = { - target, - kind, - index: 0 - }; - return iterator; -} + if (v === "") { + url.query = null; + return; + } -const HeadersIteratorPrototype = Object.setPrototypeOf({ - next() { - // istanbul ignore if - if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { - throw new TypeError('Value of `this` is not a HeadersIterator'); - } + const input = v[0] === "?" ? v.substring(1) : v; + url.query = ""; + usm.basicURLParse(input, { url, stateOverride: "query" }); + } - var _INTERNAL = this[INTERNAL]; - const target = _INTERNAL.target, - kind = _INTERNAL.kind, - index = _INTERNAL.index; + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } - const values = getHeaders(target, kind); - const len = values.length; - if (index >= len) { - return { - value: undefined, - done: true - }; - } + return "#" + this._url.fragment; + } - this[INTERNAL].index = index + 1; + set hash(v) { + if (v === "") { + this._url.fragment = null; + return; + } - return { - value: values[index], - done: false - }; - } -}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + const input = v[0] === "#" ? v.substring(1) : v; + this._url.fragment = ""; + usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); + } -Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { - value: 'HeadersIterator', - writable: false, - enumerable: false, - configurable: true -}); + toJSON() { + return this.href; + } +}; -/** - * Export the Headers object in a form that Node.js can consume. - * - * @param Headers headers - * @return Object - */ -function exportNodeCompatibleHeaders(headers) { - const obj = Object.assign({ __proto__: null }, headers[MAP]); - // http.request() only supports string as Host header. This hack makes - // specifying custom Host header possible. - const hostHeaderKey = find(headers[MAP], 'Host'); - if (hostHeaderKey !== undefined) { - obj[hostHeaderKey] = obj[hostHeaderKey][0]; - } +/***/ }), - return obj; -} - -/** - * Create a Headers object from an object of headers, ignoring those that do - * not conform to HTTP grammar productions. - * - * @param Object obj Object of headers - * @return Headers - */ -function createHeadersLenient(obj) { - const headers = new Headers(); - for (const name of Object.keys(obj)) { - if (invalidTokenRegex.test(name)) { - continue; - } - if (Array.isArray(obj[name])) { - for (const val of obj[name]) { - if (invalidHeaderCharRegex.test(val)) { - continue; - } - if (headers[MAP][name] === undefined) { - headers[MAP][name] = [val]; - } else { - headers[MAP][name].push(val); - } - } - } else if (!invalidHeaderCharRegex.test(obj[name])) { - headers[MAP][name] = [obj[name]]; - } - } - return headers; -} - -const INTERNALS$1 = Symbol('Response internals'); - -// fix an issue where "STATUS_CODES" aren't a named export for node <10 -const STATUS_CODES = http.STATUS_CODES; - -/** - * Response class - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -class Response { - constructor() { - let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +/***/ 653: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - Body.call(this, body, opts); +"use strict"; - const status = opts.status || 200; - const headers = new Headers(opts.headers); - if (body != null && !headers.has('Content-Type')) { - const contentType = extractContentType(body); - if (contentType) { - headers.append('Content-Type', contentType); - } - } +const conversions = __nccwpck_require__(5871); +const utils = __nccwpck_require__(276); +const Impl = __nccwpck_require__(8262); - this[INTERNALS$1] = { - url: opts.url, - status, - statusText: opts.statusText || STATUS_CODES[status], - headers, - counter: opts.counter - }; - } +const impl = utils.implSymbol; - get url() { - return this[INTERNALS$1].url || ''; - } +function URL(url) { + if (!this || this[impl] || !(this instanceof URL)) { + throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); + } + if (arguments.length < 1) { + throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); + } + const args = []; + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i]; + } + args[0] = conversions["USVString"](args[0]); + if (args[1] !== undefined) { + args[1] = conversions["USVString"](args[1]); + } - get status() { - return this[INTERNALS$1].status; - } + module.exports.setup(this, args); +} - /** - * Convenience property representing if the request ended normally - */ - get ok() { - return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; - } +URL.prototype.toJSON = function toJSON() { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + const args = []; + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i]; + } + return this[impl].toJSON.apply(this[impl], args); +}; +Object.defineProperty(URL.prototype, "href", { + get() { + return this[impl].href; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].href = V; + }, + enumerable: true, + configurable: true +}); - get redirected() { - return this[INTERNALS$1].counter > 0; - } +URL.prototype.toString = function () { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + return this.href; +}; - get statusText() { - return this[INTERNALS$1].statusText; - } +Object.defineProperty(URL.prototype, "origin", { + get() { + return this[impl].origin; + }, + enumerable: true, + configurable: true +}); - get headers() { - return this[INTERNALS$1].headers; - } +Object.defineProperty(URL.prototype, "protocol", { + get() { + return this[impl].protocol; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].protocol = V; + }, + enumerable: true, + configurable: true +}); - /** - * Clone this response - * - * @return Response - */ - clone() { - return new Response(clone(this), { - url: this.url, - status: this.status, - statusText: this.statusText, - headers: this.headers, - ok: this.ok, - redirected: this.redirected - }); - } -} +Object.defineProperty(URL.prototype, "username", { + get() { + return this[impl].username; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].username = V; + }, + enumerable: true, + configurable: true +}); -Body.mixIn(Response.prototype); +Object.defineProperty(URL.prototype, "password", { + get() { + return this[impl].password; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].password = V; + }, + enumerable: true, + configurable: true +}); -Object.defineProperties(Response.prototype, { - url: { enumerable: true }, - status: { enumerable: true }, - ok: { enumerable: true }, - redirected: { enumerable: true }, - statusText: { enumerable: true }, - headers: { enumerable: true }, - clone: { enumerable: true } +Object.defineProperty(URL.prototype, "host", { + get() { + return this[impl].host; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].host = V; + }, + enumerable: true, + configurable: true }); -Object.defineProperty(Response.prototype, Symbol.toStringTag, { - value: 'Response', - writable: false, - enumerable: false, - configurable: true +Object.defineProperty(URL.prototype, "hostname", { + get() { + return this[impl].hostname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hostname = V; + }, + enumerable: true, + configurable: true }); -const INTERNALS$2 = Symbol('Request internals'); -const URL = Url.URL || whatwgUrl.URL; +Object.defineProperty(URL.prototype, "port", { + get() { + return this[impl].port; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].port = V; + }, + enumerable: true, + configurable: true +}); -// fix an issue where "format", "parse" aren't a named export for node <10 -const parse_url = Url.parse; -const format_url = Url.format; +Object.defineProperty(URL.prototype, "pathname", { + get() { + return this[impl].pathname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].pathname = V; + }, + enumerable: true, + configurable: true +}); -/** - * Wrapper around `new URL` to handle arbitrary URLs - * - * @param {string} urlStr - * @return {void} - */ -function parseURL(urlStr) { - /* - Check whether the URL is absolute or not - Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 - Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 - */ - if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { - urlStr = new URL(urlStr).toString(); - } - - // Fallback to old implementation for arbitrary URLs - return parse_url(urlStr); -} - -const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; - -/** - * Check if a value is an instance of Request. - * - * @param Mixed input - * @return Boolean - */ -function isRequest(input) { - return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; -} - -function isAbortSignal(signal) { - const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); - return !!(proto && proto.constructor.name === 'AbortSignal'); -} - -/** - * Request class - * - * @param Mixed input Url or Request instance - * @param Object init Custom options - * @return Void - */ -class Request { - constructor(input) { - let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - let parsedURL; - - // normalize input - if (!isRequest(input)) { - if (input && input.href) { - // in order to support Node.js' Url objects; though WHATWG's URL objects - // will fall into this branch also (since their `toString()` will return - // `href` property anyway) - parsedURL = parseURL(input.href); - } else { - // coerce input to a string before attempting to parse - parsedURL = parseURL(`${input}`); - } - input = {}; - } else { - parsedURL = parseURL(input.url); - } - - let method = init.method || input.method || 'GET'; - method = method.toUpperCase(); - - if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { - throw new TypeError('Request with GET/HEAD method cannot have body'); - } - - let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; - - Body.call(this, inputBody, { - timeout: init.timeout || input.timeout || 0, - size: init.size || input.size || 0 - }); - - const headers = new Headers(init.headers || input.headers || {}); - - if (inputBody != null && !headers.has('Content-Type')) { - const contentType = extractContentType(inputBody); - if (contentType) { - headers.append('Content-Type', contentType); - } - } - - let signal = isRequest(input) ? input.signal : null; - if ('signal' in init) signal = init.signal; - - if (signal != null && !isAbortSignal(signal)) { - throw new TypeError('Expected signal to be an instanceof AbortSignal'); - } - - this[INTERNALS$2] = { - method, - redirect: init.redirect || input.redirect || 'follow', - headers, - parsedURL, - signal - }; - - // node-fetch-only options - this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; - this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; - this.counter = init.counter || input.counter || 0; - this.agent = init.agent || input.agent; - } - - get method() { - return this[INTERNALS$2].method; - } - - get url() { - return format_url(this[INTERNALS$2].parsedURL); - } - - get headers() { - return this[INTERNALS$2].headers; - } +Object.defineProperty(URL.prototype, "search", { + get() { + return this[impl].search; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].search = V; + }, + enumerable: true, + configurable: true +}); - get redirect() { - return this[INTERNALS$2].redirect; - } +Object.defineProperty(URL.prototype, "hash", { + get() { + return this[impl].hash; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hash = V; + }, + enumerable: true, + configurable: true +}); - get signal() { - return this[INTERNALS$2].signal; - } - /** - * Clone this request - * - * @return Request - */ - clone() { - return new Request(this); - } -} +module.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation; + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL.prototype); + this.setup(obj, constructorArgs, privateData); + return obj; + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {}; + privateData.wrapper = obj; -Body.mixIn(Request.prototype); + obj[impl] = new Impl.implementation(constructorArgs, privateData); + obj[impl][utils.wrapperSymbol] = obj; + }, + interface: URL, + expose: { + Window: { URL: URL }, + Worker: { URL: URL } + } +}; -Object.defineProperty(Request.prototype, Symbol.toStringTag, { - value: 'Request', - writable: false, - enumerable: false, - configurable: true -}); -Object.defineProperties(Request.prototype, { - method: { enumerable: true }, - url: { enumerable: true }, - headers: { enumerable: true }, - redirect: { enumerable: true }, - clone: { enumerable: true }, - signal: { enumerable: true } -}); -/** - * Convert a Request to Node.js http request options. - * - * @param Request A Request instance - * @return Object The options object to be passed to http.request - */ -function getNodeRequestOptions(request) { - const parsedURL = request[INTERNALS$2].parsedURL; - const headers = new Headers(request[INTERNALS$2].headers); +/***/ }), - // fetch step 1.3 - if (!headers.has('Accept')) { - headers.set('Accept', '*/*'); - } +/***/ 3323: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // Basic fetch - if (!parsedURL.protocol || !parsedURL.hostname) { - throw new TypeError('Only absolute URLs are supported'); - } +"use strict"; - if (!/^https?:$/.test(parsedURL.protocol)) { - throw new TypeError('Only HTTP(S) protocols are supported'); - } - if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { - throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); - } +exports.URL = __nccwpck_require__(653)["interface"]; +exports.serializeURL = __nccwpck_require__(33).serializeURL; +exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; +exports.basicURLParse = __nccwpck_require__(33).basicURLParse; +exports.setTheUsername = __nccwpck_require__(33).setTheUsername; +exports.setThePassword = __nccwpck_require__(33).setThePassword; +exports.serializeHost = __nccwpck_require__(33).serializeHost; +exports.serializeInteger = __nccwpck_require__(33).serializeInteger; +exports.parseURL = __nccwpck_require__(33).parseURL; - // HTTP-network-or-cache fetch steps 2.4-2.7 - let contentLengthValue = null; - if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { - contentLengthValue = '0'; - } - if (request.body != null) { - const totalBytes = getTotalBytes(request); - if (typeof totalBytes === 'number') { - contentLengthValue = String(totalBytes); - } - } - if (contentLengthValue) { - headers.set('Content-Length', contentLengthValue); - } - // HTTP-network-or-cache fetch step 2.11 - if (!headers.has('User-Agent')) { - headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); - } +/***/ }), - // HTTP-network-or-cache fetch step 2.15 - if (request.compress && !headers.has('Accept-Encoding')) { - headers.set('Accept-Encoding', 'gzip,deflate'); - } - - let agent = request.agent; - if (typeof agent === 'function') { - agent = agent(parsedURL); - } - - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close'); - } - - // HTTP-network fetch step 4.2 - // chunked encoding is handled by Node.js - - return Object.assign({}, parsedURL, { - method: request.method, - headers: exportNodeCompatibleHeaders(headers), - agent - }); -} - -/** - * abort-error.js - * - * AbortError interface for cancelled requests - */ - -/** - * Create AbortError instance - * - * @param String message Error message for human - * @return AbortError - */ -function AbortError(message) { - Error.call(this, message); - - this.type = 'aborted'; - this.message = message; - - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} - -AbortError.prototype = Object.create(Error.prototype); -AbortError.prototype.constructor = AbortError; -AbortError.prototype.name = 'AbortError'; - -const URL$1 = Url.URL || whatwgUrl.URL; - -// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 -const PassThrough$1 = Stream.PassThrough; - -const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { - const orig = new URL$1(original).hostname; - const dest = new URL$1(destination).hostname; - - return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); -}; - -/** - * Fetch function - * - * @param Mixed url Absolute url or Request instance - * @param Object opts Fetch options - * @return Promise - */ -function fetch(url, opts) { - - // allow custom promise - if (!fetch.Promise) { - throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); - } - - Body.Promise = fetch.Promise; - - // wrap http.request into fetch - return new fetch.Promise(function (resolve, reject) { - // build request object - const request = new Request(url, opts); - const options = getNodeRequestOptions(request); - - const send = (options.protocol === 'https:' ? https : http).request; - const signal = request.signal; - - let response = null; - - const abort = function abort() { - let error = new AbortError('The user aborted a request.'); - reject(error); - if (request.body && request.body instanceof Stream.Readable) { - request.body.destroy(error); - } - if (!response || !response.body) return; - response.body.emit('error', error); - }; - - if (signal && signal.aborted) { - abort(); - return; - } - - const abortAndFinalize = function abortAndFinalize() { - abort(); - finalize(); - }; - - // send request - const req = send(options); - let reqTimeout; - - if (signal) { - signal.addEventListener('abort', abortAndFinalize); - } - - function finalize() { - req.abort(); - if (signal) signal.removeEventListener('abort', abortAndFinalize); - clearTimeout(reqTimeout); - } - - if (request.timeout) { - req.once('socket', function (socket) { - reqTimeout = setTimeout(function () { - reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); - finalize(); - }, request.timeout); - }); - } - - req.on('error', function (err) { - reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); - finalize(); - }); - - req.on('response', function (res) { - clearTimeout(reqTimeout); - - const headers = createHeadersLenient(res.headers); - - // HTTP fetch step 5 - if (fetch.isRedirect(res.statusCode)) { - // HTTP fetch step 5.2 - const location = headers.get('Location'); - - // HTTP fetch step 5.3 - let locationURL = null; - try { - locationURL = location === null ? null : new URL$1(location, request.url).toString(); - } catch (err) { - // error here can only be invalid URL in Location: header - // do not throw when options.redirect == manual - // let the user extract the errorneous redirect URL - if (request.redirect !== 'manual') { - reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); - finalize(); - return; - } - } - - // HTTP fetch step 5.5 - switch (request.redirect) { - case 'error': - reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); - finalize(); - return; - case 'manual': - // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. - if (locationURL !== null) { - // handle corrupted header - try { - headers.set('Location', locationURL); - } catch (err) { - // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request - reject(err); - } - } - break; - case 'follow': - // HTTP-redirect fetch step 2 - if (locationURL === null) { - break; - } - - // HTTP-redirect fetch step 5 - if (request.counter >= request.follow) { - reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 6 (counter increment) - // Create a new Request object. - const requestOpts = { - headers: new Headers(request.headers), - follow: request.follow, - counter: request.counter + 1, - agent: request.agent, - compress: request.compress, - method: request.method, - body: request.body, - signal: request.signal, - timeout: request.timeout, - size: request.size - }; - - if (!isDomainOrSubdomain(request.url, locationURL)) { - for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { - requestOpts.headers.delete(name); - } - } - - // HTTP-redirect fetch step 9 - if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { - reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 11 - if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { - requestOpts.method = 'GET'; - requestOpts.body = undefined; - requestOpts.headers.delete('content-length'); - } - - // HTTP-redirect fetch step 15 - resolve(fetch(new Request(locationURL, requestOpts))); - finalize(); - return; - } - } - - // prepare response - res.once('end', function () { - if (signal) signal.removeEventListener('abort', abortAndFinalize); - }); - let body = res.pipe(new PassThrough$1()); - - const response_options = { - url: request.url, - status: res.statusCode, - statusText: res.statusMessage, - headers: headers, - size: request.size, - timeout: request.timeout, - counter: request.counter - }; - - // HTTP-network fetch step 12.1.1.3 - const codings = headers.get('Content-Encoding'); - - // HTTP-network fetch step 12.1.1.4: handle content codings - - // in following scenarios we ignore compression support - // 1. compression support is disabled - // 2. HEAD request - // 3. no Content-Encoding header - // 4. no content response (204) - // 5. content not modified response (304) - if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { - response = new Response(body, response_options); - resolve(response); - return; - } - - // For Node v6+ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - const zlibOptions = { - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH - }; - - // for gzip - if (codings == 'gzip' || codings == 'x-gzip') { - body = body.pipe(zlib.createGunzip(zlibOptions)); - response = new Response(body, response_options); - resolve(response); - return; - } - - // for deflate - if (codings == 'deflate' || codings == 'x-deflate') { - // handle the infamous raw deflate response from old servers - // a hack for old IIS and Apache servers - const raw = res.pipe(new PassThrough$1()); - raw.once('data', function (chunk) { - // see http://stackoverflow.com/questions/37519828 - if ((chunk[0] & 0x0F) === 0x08) { - body = body.pipe(zlib.createInflate()); - } else { - body = body.pipe(zlib.createInflateRaw()); - } - response = new Response(body, response_options); - resolve(response); - }); - return; - } - - // for br - if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { - body = body.pipe(zlib.createBrotliDecompress()); - response = new Response(body, response_options); - resolve(response); - return; - } - - // otherwise, use response as-is - response = new Response(body, response_options); - resolve(response); - }); - - writeToStream(req, request); - }); -} -/** - * Redirect code matching - * - * @param Number code Status code - * @return Boolean - */ -fetch.isRedirect = function (code) { - return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; -}; - -// expose Promise -fetch.Promise = global.Promise; - -module.exports = exports = fetch; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports; -exports.Headers = Headers; -exports.Request = Request; -exports.Response = Response; -exports.FetchError = FetchError; - - -/***/ }), - -/***/ 2299: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -var punycode = __nccwpck_require__(5477); -var mappingTable = __nccwpck_require__(1907); - -var PROCESSING_OPTIONS = { - TRANSITIONAL: 0, - NONTRANSITIONAL: 1 -}; - -function normalize(str) { // fix bug in v8 - return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); -} - -function findStatus(val) { - var start = 0; - var end = mappingTable.length - 1; - - while (start <= end) { - var mid = Math.floor((start + end) / 2); - - var target = mappingTable[mid]; - if (target[0][0] <= val && target[0][1] >= val) { - return target; - } else if (target[0][0] > val) { - end = mid - 1; - } else { - start = mid + 1; - } - } - - return null; -} - -var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; - -function countSymbols(string) { - return string - // replace every surrogate pair with a BMP symbol - .replace(regexAstralSymbols, '_') - // then get the length - .length; -} - -function mapChars(domain_name, useSTD3, processing_option) { - var hasError = false; - var processed = ""; - - var len = countSymbols(domain_name); - for (var i = 0; i < len; ++i) { - var codePoint = domain_name.codePointAt(i); - var status = findStatus(codePoint); - - switch (status[1]) { - case "disallowed": - hasError = true; - processed += String.fromCodePoint(codePoint); - break; - case "ignored": - break; - case "mapped": - processed += String.fromCodePoint.apply(String, status[2]); - break; - case "deviation": - if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { - processed += String.fromCodePoint.apply(String, status[2]); - } else { - processed += String.fromCodePoint(codePoint); - } - break; - case "valid": - processed += String.fromCodePoint(codePoint); - break; - case "disallowed_STD3_mapped": - if (useSTD3) { - hasError = true; - processed += String.fromCodePoint(codePoint); - } else { - processed += String.fromCodePoint.apply(String, status[2]); - } - break; - case "disallowed_STD3_valid": - if (useSTD3) { - hasError = true; - } - - processed += String.fromCodePoint(codePoint); - break; - } - } - - return { - string: processed, - error: hasError - }; -} - -var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; - -function validateLabel(label, processing_option) { - if (label.substr(0, 4) === "xn--") { - label = punycode.toUnicode(label); - processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; - } - - var error = false; - - if (normalize(label) !== label || - (label[3] === "-" && label[4] === "-") || - label[0] === "-" || label[label.length - 1] === "-" || - label.indexOf(".") !== -1 || - label.search(combiningMarksRegex) === 0) { - error = true; - } - - var len = countSymbols(label); - for (var i = 0; i < len; ++i) { - var status = findStatus(label.codePointAt(i)); - if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || - (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && - status[1] !== "valid" && status[1] !== "deviation")) { - error = true; - break; - } - } - - return { - label: label, - error: error - }; -} - -function processing(domain_name, useSTD3, processing_option) { - var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize(result.string); - - var labels = result.string.split("."); - for (var i = 0; i < labels.length; ++i) { - try { - var validation = validateLabel(labels[i]); - labels[i] = validation.label; - result.error = result.error || validation.error; - } catch(e) { - result.error = true; - } - } - - return { - string: labels.join("."), - error: result.error - }; -} - -module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { - var result = processing(domain_name, useSTD3, processing_option); - var labels = result.string.split("."); - labels = labels.map(function(l) { - try { - return punycode.toASCII(l); - } catch(e) { - result.error = true; - return l; - } - }); - - if (verifyDnsLength) { - var total = labels.slice(0, labels.length - 1).join(".").length; - if (total.length > 253 || total.length === 0) { - result.error = true; - } - - for (var i=0; i < labels.length; ++i) { - if (labels.length > 63 || labels.length === 0) { - result.error = true; - break; - } - } - } - - if (result.error) return null; - return labels.join("."); -}; - -module.exports.toUnicode = function(domain_name, useSTD3) { - var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - - return { - domain: result.string, - error: result.error - }; -}; - -module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - - -/***/ }), - -/***/ 5871: -/***/ ((module) => { - -"use strict"; - - -var conversions = {}; -module.exports = conversions; - -function sign(x) { - return x < 0 ? -1 : 1; -} - -function evenRound(x) { - // Round x to the nearest integer, choosing the even integer if it lies halfway between two. - if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) - return Math.floor(x); - } else { - return Math.round(x); - } -} - -function createNumberConversion(bitLength, typeOpts) { - if (!typeOpts.unsigned) { - --bitLength; - } - const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); - const upperBound = Math.pow(2, bitLength) - 1; - - const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); - const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - - return function(V, opts) { - if (!opts) opts = {}; - - let x = +V; - - if (opts.enforceRange) { - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite number"); - } - - x = sign(x) * Math.floor(Math.abs(x)); - if (x < lowerBound || x > upperBound) { - throw new TypeError("Argument is not in byte range"); - } - - return x; - } - - if (!isNaN(x) && opts.clamp) { - x = evenRound(x); - - if (x < lowerBound) x = lowerBound; - if (x > upperBound) x = upperBound; - return x; - } - - if (!Number.isFinite(x) || x === 0) { - return 0; - } - - x = sign(x) * Math.floor(Math.abs(x)); - x = x % moduloVal; - - if (!typeOpts.unsigned && x >= moduloBound) { - return x - moduloVal; - } else if (typeOpts.unsigned) { - if (x < 0) { - x += moduloVal; - } else if (x === -0) { // don't return negative zero - return 0; - } - } - - return x; - } -} - -conversions["void"] = function () { - return undefined; -}; - -conversions["boolean"] = function (val) { - return !!val; -}; - -conversions["byte"] = createNumberConversion(8, { unsigned: false }); -conversions["octet"] = createNumberConversion(8, { unsigned: true }); - -conversions["short"] = createNumberConversion(16, { unsigned: false }); -conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - -conversions["long"] = createNumberConversion(32, { unsigned: false }); -conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - -conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); -conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - -conversions["double"] = function (V) { - const x = +V; - - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite floating-point value"); - } - - return x; -}; - -conversions["unrestricted double"] = function (V) { - const x = +V; - - if (isNaN(x)) { - throw new TypeError("Argument is NaN"); - } - - return x; -}; - -// not quite valid, but good enough for JS -conversions["float"] = conversions["double"]; -conversions["unrestricted float"] = conversions["unrestricted double"]; - -conversions["DOMString"] = function (V, opts) { - if (!opts) opts = {}; - - if (opts.treatNullAsEmptyString && V === null) { - return ""; - } - - return String(V); -}; - -conversions["ByteString"] = function (V, opts) { - const x = String(V); - let c = undefined; - for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { - if (c > 255) { - throw new TypeError("Argument is not a valid bytestring"); - } - } - - return x; -}; - -conversions["USVString"] = function (V) { - const S = String(V); - const n = S.length; - const U = []; - for (let i = 0; i < n; ++i) { - const c = S.charCodeAt(i); - if (c < 0xD800 || c > 0xDFFF) { - U.push(String.fromCodePoint(c)); - } else if (0xDC00 <= c && c <= 0xDFFF) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - if (i === n - 1) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - const d = S.charCodeAt(i + 1); - if (0xDC00 <= d && d <= 0xDFFF) { - const a = c & 0x3FF; - const b = d & 0x3FF; - U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); - ++i; - } else { - U.push(String.fromCodePoint(0xFFFD)); - } - } - } - } - - return U.join(''); -}; - -conversions["Date"] = function (V, opts) { - if (!(V instanceof Date)) { - throw new TypeError("Argument is not a Date object"); - } - if (isNaN(V)) { - return undefined; - } - - return V; -}; - -conversions["RegExp"] = function (V, opts) { - if (!(V instanceof RegExp)) { - V = new RegExp(V); - } - - return V; -}; - - -/***/ }), - -/***/ 8262: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -const usm = __nccwpck_require__(33); - -exports.implementation = class URLImpl { - constructor(constructorArgs) { - const url = constructorArgs[0]; - const base = constructorArgs[1]; - - let parsedBase = null; - if (base !== undefined) { - parsedBase = usm.basicURLParse(base); - if (parsedBase === "failure") { - throw new TypeError("Invalid base URL"); - } - } - - const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - - // TODO: query stuff - } - - get href() { - return usm.serializeURL(this._url); - } - - set href(v) { - const parsedURL = usm.basicURLParse(v); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - } - - get origin() { - return usm.serializeURLOrigin(this._url); - } - - get protocol() { - return this._url.scheme + ":"; - } - - set protocol(v) { - usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); - } - - get username() { - return this._url.username; - } - - set username(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setTheUsername(this._url, v); - } - - get password() { - return this._url.password; - } - - set password(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setThePassword(this._url, v); - } - - get host() { - const url = this._url; - - if (url.host === null) { - return ""; - } - - if (url.port === null) { - return usm.serializeHost(url.host); - } - - return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); - } - - set host(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); - } - - get hostname() { - if (this._url.host === null) { - return ""; - } - - return usm.serializeHost(this._url.host); - } - - set hostname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); - } - - get port() { - if (this._url.port === null) { - return ""; - } - - return usm.serializeInteger(this._url.port); - } - - set port(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - if (v === "") { - this._url.port = null; - } else { - usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); - } - } - - get pathname() { - if (this._url.cannotBeABaseURL) { - return this._url.path[0]; - } - - if (this._url.path.length === 0) { - return ""; - } - - return "/" + this._url.path.join("/"); - } - - set pathname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - this._url.path = []; - usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); - } - - get search() { - if (this._url.query === null || this._url.query === "") { - return ""; - } - - return "?" + this._url.query; - } - - set search(v) { - // TODO: query stuff - - const url = this._url; - - if (v === "") { - url.query = null; - return; - } - - const input = v[0] === "?" ? v.substring(1) : v; - url.query = ""; - usm.basicURLParse(input, { url, stateOverride: "query" }); - } - - get hash() { - if (this._url.fragment === null || this._url.fragment === "") { - return ""; - } - - return "#" + this._url.fragment; - } - - set hash(v) { - if (v === "") { - this._url.fragment = null; - return; - } - - const input = v[0] === "#" ? v.substring(1) : v; - this._url.fragment = ""; - usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); - } - - toJSON() { - return this.href; - } -}; - - -/***/ }), - -/***/ 653: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const conversions = __nccwpck_require__(5871); -const utils = __nccwpck_require__(276); -const Impl = __nccwpck_require__(8262); - -const impl = utils.implSymbol; - -function URL(url) { - if (!this || this[impl] || !(this instanceof URL)) { - throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); - } - if (arguments.length < 1) { - throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); - } - const args = []; - for (let i = 0; i < arguments.length && i < 2; ++i) { - args[i] = arguments[i]; - } - args[0] = conversions["USVString"](args[0]); - if (args[1] !== undefined) { - args[1] = conversions["USVString"](args[1]); - } - - module.exports.setup(this, args); -} - -URL.prototype.toJSON = function toJSON() { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - const args = []; - for (let i = 0; i < arguments.length && i < 0; ++i) { - args[i] = arguments[i]; - } - return this[impl].toJSON.apply(this[impl], args); -}; -Object.defineProperty(URL.prototype, "href", { - get() { - return this[impl].href; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].href = V; - }, - enumerable: true, - configurable: true -}); - -URL.prototype.toString = function () { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - return this.href; -}; - -Object.defineProperty(URL.prototype, "origin", { - get() { - return this[impl].origin; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "protocol", { - get() { - return this[impl].protocol; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].protocol = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "username", { - get() { - return this[impl].username; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].username = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "password", { - get() { - return this[impl].password; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].password = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "host", { - get() { - return this[impl].host; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].host = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hostname", { - get() { - return this[impl].hostname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hostname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "port", { - get() { - return this[impl].port; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].port = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "pathname", { - get() { - return this[impl].pathname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].pathname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "search", { - get() { - return this[impl].search; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].search = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hash", { - get() { - return this[impl].hash; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hash = V; - }, - enumerable: true, - configurable: true -}); - - -module.exports = { - is(obj) { - return !!obj && obj[impl] instanceof Impl.implementation; - }, - create(constructorArgs, privateData) { - let obj = Object.create(URL.prototype); - this.setup(obj, constructorArgs, privateData); - return obj; - }, - setup(obj, constructorArgs, privateData) { - if (!privateData) privateData = {}; - privateData.wrapper = obj; - - obj[impl] = new Impl.implementation(constructorArgs, privateData); - obj[impl][utils.wrapperSymbol] = obj; - }, - interface: URL, - expose: { - Window: { URL: URL }, - Worker: { URL: URL } - } -}; - - - -/***/ }), - -/***/ 3323: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -exports.URL = __nccwpck_require__(653)["interface"]; -exports.serializeURL = __nccwpck_require__(33).serializeURL; -exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; -exports.basicURLParse = __nccwpck_require__(33).basicURLParse; -exports.setTheUsername = __nccwpck_require__(33).setTheUsername; -exports.setThePassword = __nccwpck_require__(33).setThePassword; -exports.serializeHost = __nccwpck_require__(33).serializeHost; -exports.serializeInteger = __nccwpck_require__(33).serializeInteger; -exports.parseURL = __nccwpck_require__(33).parseURL; - - -/***/ }), - -/***/ 33: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 33: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; @@ -12851,478 +10695,811 @@ module.exports.parseURL = function (input, options) { }; -/***/ }), +/***/ }), + +/***/ 276: +/***/ ((module) => { + +"use strict"; + + +module.exports.mixin = function mixin(target, source) { + const keys = Object.getOwnPropertyNames(source); + for (let i = 0; i < keys.length; ++i) { + Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); + } +}; + +module.exports.wrapperSymbol = Symbol("wrapper"); +module.exports.implSymbol = Symbol("impl"); + +module.exports.wrapperForImpl = function (impl) { + return impl[module.exports.wrapperSymbol]; +}; + +module.exports.implForWrapper = function (wrapper) { + return wrapper[module.exports.implSymbol]; +}; + + + +/***/ }), + +/***/ 1223: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var wrappy = __nccwpck_require__(2940) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + + +/***/ }), + +/***/ 4294: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = __nccwpck_require__(4219); + + +/***/ }), + +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), + +/***/ 5030: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function getUserAgent() { + if (typeof navigator === "object" && "userAgent" in navigator) { + return navigator.userAgent; + } + + if (typeof process === "object" && "version" in process) { + return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; + } + + return ""; +} + +exports.getUserAgent = getUserAgent; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); -/***/ 276: -/***/ ((module) => { +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); -"use strict"; +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); -module.exports.mixin = function mixin(target, source) { - const keys = Object.getOwnPropertyNames(source); - for (let i = 0; i < keys.length; ++i) { - Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); - } -}; +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); -module.exports.wrapperSymbol = Symbol("wrapper"); -module.exports.implSymbol = Symbol("impl"); +var _version = _interopRequireDefault(__nccwpck_require__(1595)); -module.exports.wrapperForImpl = function (impl) { - return impl[module.exports.wrapperSymbol]; -}; +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -module.exports.implForWrapper = function (wrapper) { - return wrapper[module.exports.implSymbol]; -}; +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), -/***/ 1223: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var wrappy = __nccwpck_require__(2940) -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) +"use strict"; -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f + + return _crypto.default.createHash('md5').update(bytes).digest(); } +var _default = md5; +exports["default"] = _default; /***/ }), -/***/ 4294: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; -module.exports = __nccwpck_require__(4219); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; /***/ }), -/***/ 4219: +/***/ 2746: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var net = __nccwpck_require__(1808); -var tls = __nccwpck_require__(4404); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var events = __nccwpck_require__(2361); -var assert = __nccwpck_require__(9491); -var util = __nccwpck_require__(3837); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; -} + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; } +var _default = parse; +exports["default"] = _default; -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; +/***/ }), - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } - } - socket.destroy(); - self.removeSocket(socket); - }); -} -util.inherits(TunnelingAgent, events.EventEmitter); +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); +"use strict"; - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; + +/***/ }), + +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; + +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); + + poolPtr = 0; } - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} - function onFree() { - self.emit('free', socket, options); - } +/***/ }), + +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; +"use strict"; -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false, - headers: { - host: options.host + ':' + options.port - } - }); - if (options.localAddress) { - connectOptions.localAddress = options.localAddress; - } - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); } - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); + return _crypto.default.createHash('sha1').update(bytes).digest(); +} - if (res.statusCode !== 200) { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - socket.destroy(); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - if (head.length > 0) { - debug('got illegal response body from proxy'); - socket.destroy(); - var error = new Error('got illegal response body from proxy'); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - return cb(socket); - } +var _default = sha1; +exports["default"] = _default; - function onError(cause) { - connectReq.removeAllListeners(); +/***/ }), - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; - } - this.sockets.splice(pos, 1); +"use strict"; - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); - } -}; -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); - }); -} +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; - } - return host; // for v0.11 or later -} +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } - } - return target; +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); } +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); - } - console.error.apply(console, args); + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); } -} else { - debug = function() {}; + + return uuid; } -exports.debug = debug; // for test +var _default = stringify; +exports["default"] = _default; /***/ }), -/***/ 5030: -/***/ ((__unused_webpack_module, exports) => { +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -function getUserAgent() { - if (typeof navigator === "object" && "userAgent" in navigator) { - return navigator.userAgent; - } +var _rng = _interopRequireDefault(__nccwpck_require__(807)); - if (typeof process === "object" && "version" in process) { - return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; - } +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - return ""; -} -exports.getUserAgent = getUserAgent; -//# sourceMappingURL=index.js.map + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) -/***/ }), + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression -/***/ 5840: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval -"use strict"; + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -Object.defineProperty(exports, "v1", ({ - enumerable: true, - get: function () { - return _v.default; - } -})); -Object.defineProperty(exports, "v3", ({ - enumerable: true, - get: function () { - return _v2.default; - } -})); -Object.defineProperty(exports, "v4", ({ - enumerable: true, - get: function () { - return _v3.default; - } -})); -Object.defineProperty(exports, "v5", ({ - enumerable: true, - get: function () { - return _v4.default; - } -})); -Object.defineProperty(exports, "NIL", ({ - enumerable: true, - get: function () { - return _nil.default; - } -})); -Object.defineProperty(exports, "version", ({ - enumerable: true, - get: function () { - return _version.default; - } -})); -Object.defineProperty(exports, "validate", ({ - enumerable: true, - get: function () { - return _validate.default; - } -})); -Object.defineProperty(exports, "stringify", ({ - enumerable: true, - get: function () { - return _stringify.default; - } -})); -Object.defineProperty(exports, "parse", ({ - enumerable: true, - get: function () { - return _parse.default; + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); } -})); -var _v = _interopRequireDefault(__nccwpck_require__(8628)); + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch -var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); + msecs += 12219292800000; // `time_low` -var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` -var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` -var _nil = _interopRequireDefault(__nccwpck_require__(5332)); + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version -var _version = _interopRequireDefault(__nccwpck_require__(1595)); + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + b[i++] = clockseq & 0xff; // `node` -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return buf || (0, _stringify.default)(b); +} + +var _default = v1; +exports["default"] = _default; /***/ }), -/***/ 4569: +/***/ 6409: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -13333,27 +11510,20 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _v = _interopRequireDefault(__nccwpck_require__(5998)); -function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } +var _md = _interopRequireDefault(__nccwpck_require__(4569)); - return _crypto.default.createHash('md5').update(bytes).digest(); -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _default = md5; +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; exports["default"] = _default; /***/ }), -/***/ 5332: -/***/ ((__unused_webpack_module, exports) => { +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -13361,80 +11531,83 @@ exports["default"] = _default; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = void 0; -var _default = '00000000-0000-0000-0000-000000000000'; exports["default"] = _default; +exports.URL = exports.DNS = void 0; -/***/ }), +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); -/***/ 2746: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -"use strict"; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + const bytes = []; -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return bytes; +} -function parse(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; - let v; - const arr = new Uint8Array(16); // Parse ########-....-....-....-............ +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 0xff; - arr[2] = v >>> 8 & 0xff; - arr[3] = v & 0xff; // Parse ........-####-....-....-............ + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 0xff; // Parse ........-....-####-....-............ + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 0xff; // Parse ........-....-....-####-............ - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 0xff; // Parse ........-....-....-....-############ - // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; - arr[11] = v / 0x100000000 & 0xff; - arr[12] = v >>> 24 & 0xff; - arr[13] = v >>> 16 & 0xff; - arr[14] = v >>> 8 & 0xff; - arr[15] = v & 0xff; - return arr; -} + if (buf) { + offset = offset || 0; -var _default = parse; -exports["default"] = _default; + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } -/***/ }), + return buf; + } -/***/ 814: -/***/ ((__unused_webpack_module, exports) => { + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) -"use strict"; + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; -exports["default"] = _default; + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} /***/ }), -/***/ 807: +/***/ 5122: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -13443,29 +11616,42 @@ exports["default"] = _default; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = rng; +exports["default"] = void 0; -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate +function v4(options, buf, offset) { + options = options || {}; -let poolPtr = rnds8Pool.length; + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` -function rng() { - if (poolPtr > rnds8Pool.length - 16) { - _crypto.default.randomFillSync(rnds8Pool); - poolPtr = 0; + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; } - return rnds8Pool.slice(poolPtr, poolPtr += 16); + return (0, _stringify.default)(rnds); } +var _default = v4; +exports["default"] = _default; + /***/ }), -/***/ 5274: +/***/ 9120: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -13476,26 +11662,19 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var _v = _interopRequireDefault(__nccwpck_require__(5998)); -function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - return _crypto.default.createHash('sha1').update(bytes).digest(); -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var _default = sha1; +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; exports["default"] = _default; /***/ }), -/***/ 8950: +/***/ 6900: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -13506,42 +11685,20 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +var _regex = _interopRequireDefault(__nccwpck_require__(814)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -const byteToHex = []; - -for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).substr(1)); -} - -function stringify(arr, offset = 0) { - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields - - if (!(0, _validate.default)(uuid)) { - throw TypeError('Stringified UUID is invalid'); - } - - return uuid; +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); } -var _default = stringify; +var _default = validate; exports["default"] = _default; /***/ }), -/***/ 8628: +/***/ 1595: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; @@ -13552,530 +11709,703 @@ Object.defineProperty(exports, "__esModule", ({ })); exports["default"] = void 0; -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html -let _nodeId; - -let _clockseq; // Previous uuid creation time - - -let _lastMSecs = 0; -let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details - -function v1(options, buf, offset) { - let i = buf && offset || 0; - const b = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || _rng.default)(); - - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } - - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + return parseInt(uuid.substr(14, 1), 16); +} - let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock +var _default = version; +exports["default"] = _default; - let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) +/***/ }), - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression +/***/ 2940: +/***/ ((module) => { - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } // Per 4.2.1.2 Throw error if too many uuids are requested + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + return wrapper - if (nsecs >= 10000) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } +} - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - - msecs += 12219292800000; // `time_low` - - const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; // `time_mid` - - const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; // `time_high_and_version` - - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - - b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` +/***/ }), - b[i++] = clockseq & 0xff; // `node` +/***/ 1547: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } +"use strict"; - return buf || (0, _stringify.default)(b); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const child_process_1 = __nccwpck_require__(2081); +const CONST = __importStar(__nccwpck_require__(4097)); +const sanitizeStringForJSONParse_1 = __importDefault(__nccwpck_require__(9338)); +const VERSION_UPDATER = __importStar(__nccwpck_require__(8007)); +/** + * @param [shallowExcludeTag] When fetching the given tag, exclude all history reachable by the shallowExcludeTag (used to make fetch much faster) + */ +function fetchTag(tag, shallowExcludeTag = '') { + let shouldRetry = true; + let needsRepack = false; + while (shouldRetry) { + try { + let command = ''; + if (needsRepack) { + // We have seen some scenarios where this fixes the git fetch. + // Why? Who knows... https://github.com/Expensify/App/pull/31459 + command = 'git repack -d'; + console.log(`Running command: ${command}`); + (0, child_process_1.execSync)(command); + } + command = `git fetch origin tag ${tag} --no-tags`; + // Note that this condition is only ever NOT true in the 1.0.0-0 edge case + if (shallowExcludeTag && shallowExcludeTag !== tag) { + command += ` --shallow-exclude=${shallowExcludeTag}`; + } + console.log(`Running command: ${command}`); + (0, child_process_1.execSync)(command); + shouldRetry = false; + } + catch (e) { + console.error(e); + if (!needsRepack) { + console.log('Attempting to repack and retry...'); + needsRepack = true; + } + else { + console.error("Repack didn't help, giving up..."); + shouldRetry = false; + } + } + } +} +/** + * Get merge logs between two tags (inclusive) as a JavaScript object. + */ +function getCommitHistoryAsJSON(fromTag, toTag) { + // Fetch tags, exclude commits reachable from the previous patch version (i.e: previous checklist), so that we don't have to fetch the full history + const previousPatchVersion = VERSION_UPDATER.getPreviousVersion(fromTag, VERSION_UPDATER.SEMANTIC_VERSION_LEVELS.PATCH); + fetchTag(fromTag, previousPatchVersion); + fetchTag(toTag, previousPatchVersion); + console.log('Getting pull requests merged between the following tags:', fromTag, toTag); + return new Promise((resolve, reject) => { + let stdout = ''; + let stderr = ''; + const args = ['log', '--format={"commit": "%H", "authorName": "%an", "subject": "%s"},', `${fromTag}...${toTag}`]; + console.log(`Running command: git ${args.join(' ')}`); + const spawnedProcess = (0, child_process_1.spawn)('git', args); + spawnedProcess.on('message', console.log); + spawnedProcess.stdout.on('data', (chunk) => { + console.log(chunk.toString()); + stdout += chunk.toString(); + }); + spawnedProcess.stderr.on('data', (chunk) => { + console.error(chunk.toString()); + stderr += chunk.toString(); + }); + spawnedProcess.on('close', (code) => { + if (code !== 0) { + return reject(new Error(`${stderr}`)); + } + resolve(stdout); + }); + spawnedProcess.on('error', (err) => reject(err)); + }).then((stdout) => { + // Sanitize just the text within commit subjects as that's the only potentially un-parseable text. + const sanitizedOutput = stdout.replace(/(?<="subject": ").*?(?="})/g, (subject) => (0, sanitizeStringForJSONParse_1.default)(subject)); + // Then remove newlines, format as JSON and convert to a proper JS object + const json = `[${sanitizedOutput}]`.replace(/(\r\n|\n|\r)/gm, '').replace('},]', '}]'); + return JSON.parse(json); + }); } +/** + * Parse merged PRs, excluding those from irrelevant branches. + */ +function getValidMergedPRs(commits) { + const mergedPRs = new Set(); + commits.forEach((commit) => { + const author = commit.authorName; + if (author === CONST.OS_BOTIFY) { + return; + } + const match = commit.subject.match(/Merge pull request #(\d+) from (?!Expensify\/.*-cherry-pick-staging)/); + if (!Array.isArray(match) || match.length < 2) { + return; + } + const pr = Number.parseInt(match[1], 10); + if (mergedPRs.has(pr)) { + // If a PR shows up in the log twice, that means that the PR was deployed in the previous checklist. + // That also means that we don't want to include it in the current checklist, so we remove it now. + mergedPRs.delete(pr); + return; + } + mergedPRs.add(pr); + }); + return Array.from(mergedPRs); +} +/** + * Takes in two git tags and returns a list of PR numbers of all PRs merged between those two tags + */ +async function getPullRequestsMergedBetween(fromTag, toTag) { + console.log(`Looking for commits made between ${fromTag} and ${toTag}...`); + const commitList = await getCommitHistoryAsJSON(fromTag, toTag); + console.log(`Commits made between ${fromTag} and ${toTag}:`, commitList); + // Find which commit messages correspond to merged PR's + const pullRequestNumbers = getValidMergedPRs(commitList).sort((a, b) => a - b); + console.log(`List of pull requests merged between ${fromTag} and ${toTag}`, pullRequestNumbers); + return pullRequestNumbers; +} +exports["default"] = { + getValidMergedPRs, + getPullRequestsMergedBetween, +}; -var _default = v1; -exports["default"] = _default; - -/***/ }), - -/***/ 6409: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _md = _interopRequireDefault(__nccwpck_require__(4569)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v3 = (0, _v.default)('v3', 0x30, _md.default); -var _default = v3; -exports["default"] = _default; /***/ }), -/***/ 5998: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; })); -exports["default"] = _default; -exports.URL = exports.DNS = void 0; - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape - - const bytes = []; - - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); - } - - return bytes; -} - -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; - -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); + } + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); + } + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); + } + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); -} - -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; - -/***/ }), - -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; /***/ }), -/***/ 1547: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -const child_process_1 = __nccwpck_require__(2081); -const CONST = __importStar(__nccwpck_require__(4097)); -const sanitizeStringForJSONParse_1 = __importDefault(__nccwpck_require__(9338)); -const VERSION_UPDATER = __importStar(__nccwpck_require__(8007)); -/** - * @param [shallowExcludeTag] When fetching the given tag, exclude all history reachable by the shallowExcludeTag (used to make fetch much faster) - */ -function fetchTag(tag, shallowExcludeTag = '') { - let shouldRetry = true; - let needsRepack = false; - while (shouldRetry) { - try { - let command = ''; - if (needsRepack) { - // We have seen some scenarios where this fixes the git fetch. - // Why? Who knows... https://github.com/Expensify/App/pull/31459 - command = 'git repack -d'; - console.log(`Running command: ${command}`); - (0, child_process_1.execSync)(command); - } - command = `git fetch origin tag ${tag} --no-tags`; - // Note that this condition is only ever NOT true in the 1.0.0-0 edge case - if (shallowExcludeTag && shallowExcludeTag !== tag) { - command += ` --shallow-exclude=${shallowExcludeTag}`; - } - console.log(`Running command: ${command}`); - (0, child_process_1.execSync)(command); - shouldRetry = false; - } - catch (e) { - console.error(e); - if (!needsRepack) { - console.log('Attempting to repack and retry...'); - needsRepack = true; - } - else { - console.error("Repack didn't help, giving up..."); - shouldRetry = false; - } - } - } -} -/** - * Get merge logs between two tags (inclusive) as a JavaScript object. - */ -function getCommitHistoryAsJSON(fromTag, toTag) { - // Fetch tags, exclude commits reachable from the previous patch version (i.e: previous checklist), so that we don't have to fetch the full history - const previousPatchVersion = VERSION_UPDATER.getPreviousVersion(fromTag, VERSION_UPDATER.SEMANTIC_VERSION_LEVELS.PATCH); - fetchTag(fromTag, previousPatchVersion); - fetchTag(toTag, previousPatchVersion); - console.log('Getting pull requests merged between the following tags:', fromTag, toTag); - return new Promise((resolve, reject) => { - let stdout = ''; - let stderr = ''; - const args = ['log', '--format={"commit": "%H", "authorName": "%an", "subject": "%s"},', `${fromTag}...${toTag}`]; - console.log(`Running command: git ${args.join(' ')}`); - const spawnedProcess = (0, child_process_1.spawn)('git', args); - spawnedProcess.on('message', console.log); - spawnedProcess.stdout.on('data', (chunk) => { - console.log(chunk.toString()); - stdout += chunk.toString(); - }); - spawnedProcess.stderr.on('data', (chunk) => { - console.error(chunk.toString()); - stderr += chunk.toString(); - }); - spawnedProcess.on('close', (code) => { - if (code !== 0) { - return reject(new Error(`${stderr}`)); - } - resolve(stdout); - }); - spawnedProcess.on('error', (err) => reject(err)); - }).then((stdout) => { - // Sanitize just the text within commit subjects as that's the only potentially un-parseable text. - const sanitizedOutput = stdout.replace(/(?<="subject": ").*?(?="})/g, (subject) => (0, sanitizeStringForJSONParse_1.default)(subject)); - // Then remove newlines, format as JSON and convert to a proper JS object - const json = `[${sanitizedOutput}]`.replace(/(\r\n|\n|\r)/gm, '').replace('},]', '}]'); - return JSON.parse(json); - }); -} -/** - * Parse merged PRs, excluding those from irrelevant branches. - */ -function getValidMergedPRs(commits) { - const mergedPRs = new Set(); - commits.forEach((commit) => { - const author = commit.authorName; - if (author === CONST.OS_BOTIFY) { - return; - } - const match = commit.subject.match(/Merge pull request #(\d+) from (?!Expensify\/.*-cherry-pick-staging)/); - if (!Array.isArray(match) || match.length < 2) { - return; - } - const pr = Number.parseInt(match[1], 10); - if (mergedPRs.has(pr)) { - // If a PR shows up in the log twice, that means that the PR was deployed in the previous checklist. - // That also means that we don't want to include it in the current checklist, so we remove it now. - mergedPRs.delete(pr); - return; - } - mergedPRs.add(pr); - }); - return Array.from(mergedPRs); -} /** - * Takes in two git tags and returns a list of PR numbers of all PRs merged between those two tags + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. */ -async function getPullRequestsMergedBetween(fromTag, toTag) { - console.log(`Looking for commits made between ${fromTag} and ${toTag}...`); - const commitList = await getCommitHistoryAsJSON(fromTag, toTag); - console.log(`Commits made between ${fromTag} and ${toTag}:`, commitList); - // Find which commit messages correspond to merged PR's - const pullRequestNumbers = getValidMergedPRs(commitList).sort((a, b) => a - b); - console.log(`List of pull requests merged between ${fromTag} and ${toTag}`, pullRequestNumbers); - return pullRequestNumbers; +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } -exports["default"] = { - getValidMergedPRs, - getPullRequestsMergedBetween, -}; +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index b8d7d821d64e..71c502f6161f 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -74,784 +74,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4822,3919 +4276,2309 @@ const Endpoints = { }], renameBranch: ["POST /repos/{owner}/{repo}/branches/{branch}/rename"], replaceAllTopics: ["PUT /repos/{owner}/{repo}/topics"], - requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], - setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], - setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { - mapToData: "apps" - }], - setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { - mapToData: "contexts" - }], - setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { - mapToData: "teams" - }], - setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { - mapToData: "users" - }], - testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], - transfer: ["POST /repos/{owner}/{repo}/transfer"], - update: ["PATCH /repos/{owner}/{repo}"], - updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], - updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], - updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], - updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], - updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], + setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], + transfer: ["POST /repos/{owner}/{repo}/transfer"], + update: ["PATCH /repos/{owner}/{repo}"], + updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], + updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], + updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], + updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; + +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +"use strict"; -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = Hash; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; -module.exports = ListCache; + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ }), + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + const req = state.global.key(state.id).schedule(jobOptions, request, options); -module.exports = Map; + if (isGraphQL) { + const res = await req; + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -/***/ }), + return req; +} -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +function routeMatcher(paths) { + // EXAMPLE. For the following paths: -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -module.exports = MapCache; + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ + return new RegExp(regex, "i"); +} -/***/ }), +// @ts-expect-error -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -var root = __nccwpck_require__(9882); +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -/** Built-in value references. */ -var Symbol = root.Symbol; +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -module.exports = Symbol; + if (!enabled) { + return {}; + } + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 4356: -/***/ ((module) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling - while (++index < length) { - result[index] = iteratee(array[index], index, array); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); } - return result; -} -module.exports = arrayMap; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -/***/ }), + events.on("rate-limit", state.onRateLimit); // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -var eq = __nccwpck_require__(1901); + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } + + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + return {}; + }(); + + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; } - } - return -1; + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = assocIndexOf; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5758: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) - var index = 0, - length = path.length; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) } -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +function HookCollection () { + var state = { + registry: {} + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return hook +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return HookCollection() } -module.exports = baseIsNative; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +/***/ 5549: +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +module.exports = addHook; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} -module.exports = baseToString; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4670: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = register; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!options) { + options = {}; + } -var root = __nccwpck_require__(9882); + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -module.exports = coreJsData; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} /***/ }), -/***/ 2085: +/***/ 6819: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - +module.exports = removeHook; -/***/ }), +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + if (index === -1) { + return; + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + state.registry[name].splice(index, 1); } -module.exports = getNative; - /***/ }), -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13419,230 +11263,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), @@ -16011,7 +14341,7 @@ const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); const CONST = __nccwpck_require__(4097); const ActionUtils = __nccwpck_require__(970); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); const DEFAULT_PAYLOAD = { owner: CONST.GITHUB_OWNER, diff --git a/.github/actions/javascript/getReleaseBody/index.js b/.github/actions/javascript/getReleaseBody/index.js index cc1321ce5cd5..f07678cbaf24 100644 --- a/.github/actions/javascript/getReleaseBody/index.js +++ b/.github/actions/javascript/getReleaseBody/index.js @@ -74,784 +74,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4844,3897 +4298,2287 @@ const Endpoints = { updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; - - -/***/ }), - -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; } +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +"use strict"; -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = ListCache; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; -module.exports = Map; + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -/***/ }), + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; + const req = state.global.key(state.id).schedule(jobOptions, request, options); -/***/ }), + if (isGraphQL) { + const res = await req; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -var root = __nccwpck_require__(9882); + return req; +} -/** Built-in value references. */ -var Symbol = root.Symbol; +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -module.exports = Symbol; +function routeMatcher(paths) { + // EXAMPLE. For the following paths: + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: -/***/ }), + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -/***/ 4356: -/***/ ((module) => { + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + return new RegExp(regex, "i"); } -module.exports = arrayMap; - +// @ts-expect-error -/***/ }), +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -var eq = __nccwpck_require__(1901); +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } + if (!enabled) { + return {}; } - return -1; -} - -module.exports = assocIndexOf; + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); + } - var index = 0, - length = path.length; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -module.exports = baseGet; + events.on("rate-limit", state.onRateLimit); // @ts-expect-error + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -/***/ }), + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + return {}; + }(); -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; + } + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = baseGetTag; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 411: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseIsNative; - - -/***/ }), - -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +function HookCollection () { + var state = { + registry: {} + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; + return hook +} -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + return HookCollection() } -module.exports = baseToString; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 5549: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = addHook; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; + } -var root = __nccwpck_require__(9882); + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; + } -module.exports = coreJsData; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2085: +/***/ 4670: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; +module.exports = register; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); + } -/***/ }), + if (!options) { + options = {}; + } -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -var isKeyable = __nccwpck_require__(3308); + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); } -module.exports = getMapData; - /***/ }), -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); +/***/ 6819: +/***/ ((module) => { -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} +module.exports = removeHook; -module.exports = getNative; +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -/***/ }), + if (index === -1) { + return; + } -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + state.registry[name].splice(index, 1); +} -var Symbol = __nccwpck_require__(9213); -/** Used for built-in method references. */ -var objectProto = Object.prototype; +/***/ }), -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13574,2387 +11418,690 @@ function validate(uuid) { return typeof uuid === 'string' && _regex.default.test(uuid); } -var _default = validate; -exports["default"] = _default; - -/***/ }), - -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} - - -/***/ }), - -/***/ 2877: -/***/ ((module) => { - -module.exports = eval("require")("encoding"); - - -/***/ }), - -/***/ 9491: -/***/ ((module) => { - -"use strict"; -module.exports = require("assert"); - -/***/ }), - -/***/ 6113: -/***/ ((module) => { - -"use strict"; -module.exports = require("crypto"); - -/***/ }), - -/***/ 2361: -/***/ ((module) => { - -"use strict"; -module.exports = require("events"); - -/***/ }), - -/***/ 7147: -/***/ ((module) => { - -"use strict"; -module.exports = require("fs"); - -/***/ }), - -/***/ 3685: -/***/ ((module) => { - -"use strict"; -module.exports = require("http"); - -/***/ }), - -/***/ 5687: -/***/ ((module) => { - -"use strict"; -module.exports = require("https"); - -/***/ }), - -/***/ 1808: -/***/ ((module) => { - -"use strict"; -module.exports = require("net"); - -/***/ }), - -/***/ 2037: -/***/ ((module) => { - -"use strict"; -module.exports = require("os"); - -/***/ }), - -/***/ 1017: -/***/ ((module) => { - -"use strict"; -module.exports = require("path"); - -/***/ }), - -/***/ 5477: -/***/ ((module) => { - -"use strict"; -module.exports = require("punycode"); - -/***/ }), - -/***/ 2781: -/***/ ((module) => { - -"use strict"; -module.exports = require("stream"); - -/***/ }), - -/***/ 4404: -/***/ ((module) => { - -"use strict"; -module.exports = require("tls"); - -/***/ }), - -/***/ 7310: -/***/ ((module) => { - -"use strict"; -module.exports = require("url"); - -/***/ }), - -/***/ 3837: -/***/ ((module) => { - -"use strict"; -module.exports = require("util"); - -/***/ }), - -/***/ 9796: -/***/ ((module) => { - -"use strict"; -module.exports = require("zlib"); - -/***/ }), - -/***/ 6717: -/***/ ((__unused_webpack_module, exports) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -// Current version. -var VERSION = '1.13.6'; - -// Establish the root object, `window` (`self`) in the browser, `global` -// on the server, or `this` in some virtual machines. We use `self` -// instead of `window` for `WebWorker` support. -var root = (typeof self == 'object' && self.self === self && self) || - (typeof global == 'object' && global.global === global && global) || - Function('return this')() || - {}; - -// Save bytes in the minified (but not gzipped) version: -var ArrayProto = Array.prototype, ObjProto = Object.prototype; -var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - -// Create quick reference variables for speed access to core prototypes. -var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - -// Modern feature detection. -var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', - supportsDataView = typeof DataView !== 'undefined'; - -// All **ECMAScript 5+** native function implementations that we hope to use -// are declared here. -var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create, - nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; - -// Create references to these builtin functions because we override them. -var _isNaN = isNaN, - _isFinite = isFinite; - -// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. -var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); -var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - -// The largest integer that can be represented exactly. -var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - -// Some functions take a variable number of arguments, or a few expected -// arguments at the beginning and then a variable number of values to operate -// on. This helper accumulates all remaining arguments past the function’s -// argument length (or an explicit `startIndex`), into an array that becomes -// the last argument. Similar to ES6’s "rest parameter". -function restArguments(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; -} - -// Is a given variable an object? -function isObject(obj) { - var type = typeof obj; - return type === 'function' || (type === 'object' && !!obj); -} - -// Is a given value equal to null? -function isNull(obj) { - return obj === null; -} - -// Is a given variable undefined? -function isUndefined(obj) { - return obj === void 0; -} - -// Is a given value a boolean? -function isBoolean(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; -} - -// Is a given value a DOM element? -function isElement(obj) { - return !!(obj && obj.nodeType === 1); -} - -// Internal function for creating a `toString`-based type tester. -function tagTester(name) { - var tag = '[object ' + name + ']'; - return function(obj) { - return toString.call(obj) === tag; - }; -} - -var isString = tagTester('String'); - -var isNumber = tagTester('Number'); - -var isDate = tagTester('Date'); - -var isRegExp = tagTester('RegExp'); - -var isError = tagTester('Error'); - -var isSymbol = tagTester('Symbol'); - -var isArrayBuffer = tagTester('ArrayBuffer'); - -var isFunction = tagTester('Function'); - -// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old -// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). -var nodelist = root.document && root.document.childNodes; -if ( true && typeof Int8Array != 'object' && typeof nodelist != 'function') { - isFunction = function(obj) { - return typeof obj == 'function' || false; - }; -} - -var isFunction$1 = isFunction; - -var hasObjectTag = tagTester('Object'); +var _default = validate; +exports["default"] = _default; -// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. -// In IE 11, the most common among them, this problem also applies to -// `Map`, `WeakMap` and `Set`. -var hasStringTagBug = ( - supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) - ), - isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); +/***/ }), -var isDataView = tagTester('DataView'); +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// In IE 10 - Edge 13, we need a different heuristic -// to determine whether an object is a `DataView`. -function ie10IsDataView(obj) { - return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); -} +"use strict"; -var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); -// Is a given value an array? -// Delegates to ECMA5's native `Array.isArray`. -var isArray = nativeIsArray || tagTester('Array'); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -// Internal function to check whether `key` is an own property name of `obj`. -function has$1(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); -} +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -var isArguments = tagTester('Arguments'); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// Define a fallback version of the method in browsers (ahem, IE < 9), where -// there isn't any inspectable "Arguments" type. -(function() { - if (!isArguments(arguments)) { - isArguments = function(obj) { - return has$1(obj, 'callee'); - }; +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); } -}()); - -var isArguments$1 = isArguments; - -// Is a given object a finite number? -function isFinite$1(obj) { - return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); -} - -// Is the given value `NaN`? -function isNaN$1(obj) { - return isNumber(obj) && _isNaN(obj); -} -// Predicate-generating function. Often useful outside of Underscore. -function constant(value) { - return function() { - return value; - }; + return parseInt(uuid.substr(14, 1), 16); } -// Common internal logic for `isArrayLike` and `isBufferLike`. -function createSizePropertyCheck(getSizeProperty) { - return function(collection) { - var sizeProperty = getSizeProperty(collection); - return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; - } -} +var _default = version; +exports["default"] = _default; -// Internal helper to generate a function to obtain property `key` from `obj`. -function shallowProperty(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; -} +/***/ }), -// Internal helper to obtain the `byteLength` property of an object. -var getByteLength = shallowProperty('byteLength'); +/***/ 2940: +/***/ ((module) => { -// Internal helper to determine whether we should spend extensive checks against -// `ArrayBuffer` et al. -var isBufferLike = createSizePropertyCheck(getByteLength); +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) -// Is a given value a typed array? -var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; -function isTypedArray(obj) { - // `ArrayBuffer.isView` is the most future-proof, so use it when available. - // Otherwise, fall back on the above regular expression. - return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : - isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); -} + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) -// Internal helper to obtain the `length` property of an object. -var getLength = shallowProperty('length'); + return wrapper -// Internal helper to create a simple lookup structure. -// `collectNonEnumProps` used to depend on `_.contains`, but this led to -// circular imports. `emulatedSet` is a one-off solution that only works for -// arrays of strings. -function emulatedSet(keys) { - var hash = {}; - for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; - return { - contains: function(key) { return hash[key] === true; }, - push: function(key) { - hash[key] = true; - return keys.push(key); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] } - }; + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } } -// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't -// be iterated by `for key in ...` and thus missed. Extends `keys` in place if -// needed. -function collectNonEnumProps(obj, keys) { - keys = emulatedSet(keys); - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto; - // Constructor is a special case. - var prop = 'constructor'; - if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { - keys.push(prop); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); } - } -} - -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native `Object.keys`. -function keys(obj) { - if (!isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has$1(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -function isEmpty(obj) { - if (obj == null) return true; - // Skip the more expensive `toString`-based type checks if `obj` has no - // `.length`. - var length = getLength(obj); - if (typeof length == 'number' && ( - isArray(obj) || isString(obj) || isArguments$1(obj) - )) return length === 0; - return getLength(keys(obj)) === 0; -} - -// Returns whether an object has a given set of `key:value` pairs. -function isMatch(object, attrs) { - var _keys = keys(attrs), length = _keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = _keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; -} - -// If Underscore is called as a function, it returns a wrapped object that can -// be used OO-style. This wrapper holds altered versions of all functions added -// through `_.mixin`. Wrapped objects may be chained. -function _$1(obj) { - if (obj instanceof _$1) return obj; - if (!(this instanceof _$1)) return new _$1(obj); - this._wrapped = obj; -} - -_$1.VERSION = VERSION; - -// Extracts the result from a wrapped and chained object. -_$1.prototype.value = function() { - return this._wrapped; -}; - -// Provide unwrapping proxies for some methods used in engine operations -// such as arithmetic and JSON stringification. -_$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; - -_$1.prototype.toString = function() { - return String(this._wrapped); -}; - -// Internal function to wrap or shallow-copy an ArrayBuffer, -// typed array or DataView to a new view, reusing the buffer. -function toBufferView(bufferSource) { - return new Uint8Array( - bufferSource.buffer || bufferSource, - bufferSource.byteOffset || 0, - getByteLength(bufferSource) - ); -} - -// We use this string twice, so give it a name for minification. -var tagDataView = '[object DataView]'; - -// Internal recursive comparison function for `_.isEqual`. -function eq(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -// Internal recursive comparison function for `_.isEqual`. -function deepEq(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _$1) a = a._wrapped; - if (b instanceof _$1) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - // Work around a bug in IE 10 - Edge 13. - if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { - if (!isDataView$1(b)) return false; - className = tagDataView; - } - switch (className) { - // These types are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - case '[object ArrayBuffer]': - case tagDataView: - // Coerce to typed array so we can fall through. - return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); - } - - var areArrays = className === '[object Array]'; - if (!areArrays && isTypedArray$1(a)) { - var byteLength = getByteLength(a); - if (byteLength !== getByteLength(b)) return false; - if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; - areArrays = true; - } - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && - isFunction$1(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); } - } else { - // Deep compare objects. - var _keys = keys(a), key; - length = _keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = _keys[length]; - if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -// Perform a deep comparison to check if two objects are equal. -function isEqual(a, b) { - return eq(a, b); -} - -// Retrieve all the enumerable property names of an object. -function allKeys(obj) { - if (!isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Since the regular `Object.prototype.toString` type tests don't work for -// some types in IE 11, we use a fingerprinting heuristic instead, based -// on the methods. It's not great, but it's the best we got. -// The fingerprint method lists are defined below. -function ie11fingerprint(methods) { - var length = getLength(methods); - return function(obj) { - if (obj == null) return false; - // `Map`, `WeakMap` and `Set` have no enumerable keys. - var keys = allKeys(obj); - if (getLength(keys)) return false; - for (var i = 0; i < length; i++) { - if (!isFunction$1(obj[methods[i]])) return false; - } - // If we are testing against `WeakMap`, we need to ensure that - // `obj` doesn't have a `forEach` method in order to distinguish - // it from a regular `Map`. - return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); - }; -} - -// In the interest of compact minification, we write -// each string in the fingerprints only once. -var forEachName = 'forEach', - hasName = 'has', - commonInit = ['clear', 'delete'], - mapTail = ['get', hasName, 'set']; - -// `Map`, `WeakMap` and `Set` each have slightly different -// combinations of the above sublists. -var mapMethods = commonInit.concat(forEachName, mapTail), - weakMapMethods = commonInit.concat(mapTail), - setMethods = ['add'].concat(commonInit, forEachName, hasName); - -var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); - -var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); - -var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); - -var isWeakSet = tagTester('WeakSet'); - -// Retrieve the values of an object's properties. -function values(obj) { - var _keys = keys(obj); - var length = _keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[_keys[i]]; - } - return values; -} - -// Convert an object into a list of `[key, value]` pairs. -// The opposite of `_.object` with one argument. -function pairs(obj) { - var _keys = keys(obj); - var length = _keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [_keys[i], obj[_keys[i]]]; - } - return pairs; -} - -// Invert the keys and values of an object. The values must be serializable. -function invert(obj) { - var result = {}; - var _keys = keys(obj); - for (var i = 0, length = _keys.length; i < length; i++) { - result[obj[_keys[i]]] = _keys[i]; - } - return result; -} - -// Return a sorted list of the function names available on the object. -function functions(obj) { - var names = []; - for (var key in obj) { - if (isFunction$1(obj[key])) names.push(key); - } - return names.sort(); -} - -// An internal function for creating assigner functions. -function createAssigner(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); } - return obj; - }; -} - -// Extend a given object with all the properties in passed-in object(s). -var extend = createAssigner(allKeys); - -// Assigns a given object with all the own properties in the passed-in -// object(s). -// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) -var extendOwn = createAssigner(keys); - -// Fill in a given object with default properties. -var defaults = createAssigner(allKeys, true); - -// Create a naked function reference for surrogate-prototype-swapping. -function ctor() { - return function(){}; -} - -// An internal function for creating a new object that inherits from another. -function baseCreate(prototype) { - if (!isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - var Ctor = ctor(); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; -} - -// Creates an object that inherits from the given prototype object. -// If additional properties are provided then they will be added to the -// created object. -function create(prototype, props) { - var result = baseCreate(prototype); - if (props) extendOwn(result, props); - return result; -} - -// Create a (shallow-cloned) duplicate of an object. -function clone(obj) { - if (!isObject(obj)) return obj; - return isArray(obj) ? obj.slice() : extend({}, obj); -} - -// Invokes `interceptor` with the `obj` and then returns `obj`. -// The primary purpose of this method is to "tap into" a method chain, in -// order to perform operations on intermediate results within the chain. -function tap(obj, interceptor) { - interceptor(obj); - return obj; -} - -// Normalize a (deep) property `path` to array. -// Like `_.iteratee`, this function can be customized. -function toPath$1(path) { - return isArray(path) ? path : [path]; -} -_$1.toPath = toPath$1; - -// Internal wrapper for `_.toPath` to enable minification. -// Similar to `cb` for `_.iteratee`. -function toPath(path) { - return _$1.toPath(path); -} - -// Internal function to obtain a nested property in `obj` along `path`. -function deepGet(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; -} - -// Get the value of the (deep) property on `path` from `object`. -// If any property in `path` does not exist or if the value is -// `undefined`, return `defaultValue` instead. -// The `path` is normalized through `_.toPath`. -function get(object, path, defaultValue) { - var value = deepGet(object, toPath(path)); - return isUndefined(value) ? defaultValue : value; -} - -// Shortcut function for checking if an object has a given property directly on -// itself (in other words, not on a prototype). Unlike the internal `has` -// function, this public version can also traverse nested properties. -function has(obj, path) { - path = toPath(path); - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (!has$1(obj, key)) return false; - obj = obj[key]; - } - return !!length; -} - -// Keep the identity function around for default iteratees. -function identity(value) { - return value; -} - -// Returns a predicate for checking whether an object has a given set of -// `key:value` pairs. -function matcher(attrs) { - attrs = extendOwn({}, attrs); - return function(obj) { - return isMatch(obj, attrs); - }; -} - -// Creates a function that, when passed an object, will traverse that object’s -// properties down the given `path`, specified as an array of keys or indices. -function property(path) { - path = toPath(path); - return function(obj) { - return deepGet(obj, path); - }; -} - -// Internal function that returns an efficient (for current engines) version -// of the passed-in callback, to be repeatedly applied in other Underscore -// functions. -function optimizeCb(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; -} - -// An internal function to generate callbacks that can be applied to each -// element in a collection, returning the desired result — either `_.identity`, -// an arbitrary callback, a property matcher, or a property accessor. -function baseIteratee(value, context, argCount) { - if (value == null) return identity; - if (isFunction$1(value)) return optimizeCb(value, context, argCount); - if (isObject(value) && !isArray(value)) return matcher(value); - return property(value); -} - -// External wrapper for our callback generator. Users may customize -// `_.iteratee` if they want additional predicate/iteratee shorthand styles. -// This abstraction hides the internal-only `argCount` argument. -function iteratee(value, context) { - return baseIteratee(value, context, Infinity); -} -_$1.iteratee = iteratee; - -// The function we call internally to generate a callback. It invokes -// `_.iteratee` if overridden, otherwise `baseIteratee`. -function cb(value, context, argCount) { - if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); - return baseIteratee(value, context, argCount); -} - -// Returns the results of applying the `iteratee` to each element of `obj`. -// In contrast to `_.map` it returns an object. -function mapObject(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = keys(obj), - length = _keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = _keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Predicate-generating function. Often useful outside of Underscore. -function noop(){} - -// Generates a function for a given object that returns a given property. -function propertyOf(obj) { - if (obj == null) return noop; - return function(path) { - return get(obj, path); - }; -} - -// Run a function **n** times. -function times(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; -} - -// Return a random integer between `min` and `max` (inclusive). -function random(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); -} - -// A (possibly faster) way to get the current timestamp as an integer. -var now = Date.now || function() { - return new Date().getTime(); -}; - -// Internal helper to generate functions for escaping and unescaping strings -// to/from HTML interpolation. -function createEscaper(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; -} - -// Internal list of HTML entities for escaping. -var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' -}; - -// Function for escaping strings to HTML interpolation. -var _escape = createEscaper(escapeMap); - -// Internal list of HTML entities for unescaping. -var unescapeMap = invert(escapeMap); - -// Function for unescaping strings from HTML interpolation. -var _unescape = createEscaper(unescapeMap); - -// By default, Underscore uses ERB-style template delimiters. Change the -// following template settings to use alternative delimiters. -var templateSettings = _$1.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g -}; - -// When customizing `_.templateSettings`, if you don't want to define an -// interpolation, evaluation or escaping regex, we need one that is -// guaranteed not to match. -var noMatch = /(.)^/; - -// Certain characters need to be escaped so that they can be put into a -// string literal. -var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' -}; - -var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - -function escapeChar(match) { - return '\\' + escapes[match]; -} - -// In order to prevent third-party code injection through -// `_.templateSettings.variable`, we test it against the following regular -// expression. It is intentionally a bit more liberal than just matching valid -// identifiers, but still prevents possible loopholes through defaults or -// destructuring assignment. -var bareIdentifier = /^\s*(\w|\$)+\s*$/; - -// JavaScript micro-templating, similar to John Resig's implementation. -// Underscore templating handles arbitrary delimiters, preserves whitespace, -// and correctly escapes quotes within interpolated code. -// NB: `oldSettings` only exists for backwards compatibility. -function template(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = defaults({}, settings, _$1.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - var argument = settings.variable; - if (argument) { - // Insure against third-party code injection. (CVE-2021-23358) - if (!bareIdentifier.test(argument)) throw new Error( - 'variable is not a bare identifier: ' + argument - ); - } else { - // If a variable is not specified, place data values in local scope. - source = 'with(obj||{}){\n' + source + '}\n'; - argument = 'obj'; - } - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(argument, '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _$1); - }; - - // Provide the compiled source as a convenience for precompilation. - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; -} - -// Traverses the children of `obj` along `path`. If a child is a function, it -// is invoked with its parent as context. Returns the value of the final -// child, or `fallback` if any child is undefined. -function result(obj, path, fallback) { - path = toPath(path); - var length = path.length; - if (!length) { - return isFunction$1(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); } - obj = isFunction$1(prop) ? prop.call(obj) : prop; - } - return obj; -} - -// Generate a unique integer id (unique within the entire client session). -// Useful for temporary DOM ids. -var idCounter = 0; -function uniqueId(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; -} - -// Start chaining a wrapped Underscore object. -function chain(obj) { - var instance = _$1(obj); - instance._chain = true; - return instance; -} - -// Internal function to execute `sourceFunc` bound to `context` with optional -// `args`. Determines whether to execute a function as a constructor or as a -// normal function. -function executeBound(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (isObject(result)) return result; - return self; -} - -// Partially apply a function by creating a version that has had some of its -// arguments pre-filled, without changing its dynamic `this` context. `_` acts -// as a placeholder by default, allowing any combination of arguments to be -// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. -var partial = restArguments(function(func, boundArgs) { - var placeholder = partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; -}); - -partial.placeholder = _$1; - -// Create a function bound to a given object (assigning `this`, and arguments, -// optionally). -var bind = restArguments(function(func, context, args) { - if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; -}); - -// Internal helper for collection methods to determine whether a collection -// should be iterated as an array or as an object. -// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength -// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 -var isArrayLike = createSizePropertyCheck(getLength); - -// Internal implementation of a recursive `flatten` function. -function flatten$1(input, depth, strict, output) { - output = output || []; - if (!depth && depth !== 0) { - depth = Infinity; - } else if (depth <= 0) { - return output.concat(input); - } - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { - // Flatten current level of array or arguments object. - if (depth > 1) { - flatten$1(value, depth - 1, strict, output); - idx = output.length; - } else { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); } - } - return output; -} - -// Bind a number of an object's methods to that object. Remaining arguments -// are the method names to be bound. Useful for ensuring that all callbacks -// defined on an object belong to it. -var bindAll = restArguments(function(obj, keys) { - keys = flatten$1(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = bind(obj[key], obj); - } - return obj; -}); - -// Memoize an expensive function by storing its results. -function memoize(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; -} - -// Delays a function for the given number of milliseconds, and then calls -// it with the arguments supplied. -var delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); -}); - -// Defers a function, scheduling it to run after the current call stack has -// cleared. -var defer = partial(delay, _$1, 1); - -// Returns a function, that, when invoked, will only be triggered at most once -// during a given window of time. Normally, the throttled function will run -// as much as it can, without ever going more than once per `wait` duration; -// but if you'd like to disable the execution on the leading edge, pass -// `{leading: false}`. To disable execution on the trailing edge, ditto. -function throttle(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var _now = now(); - if (!previous && options.leading === false) previous = _now; - var remaining = wait - (_now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = _now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; -} - -// When a sequence of calls of the returned function ends, the argument -// function is triggered. The end of a sequence is defined by the `wait` -// parameter. If `immediate` is passed, the argument function will be -// triggered at the beginning of the sequence instead of at the end. -function debounce(func, wait, immediate) { - var timeout, previous, args, result, context; - - var later = function() { - var passed = now() - previous; - if (wait > passed) { - timeout = setTimeout(later, wait - passed); - } else { - timeout = null; - if (!immediate) result = func.apply(context, args); - // This check is needed because `func` can recursively invoke `debounced`. - if (!timeout) args = context = null; + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - }; - - var debounced = restArguments(function(_args) { - context = this; - args = _args; - previous = now(); - if (!timeout) { - timeout = setTimeout(later, wait); - if (immediate) result = func.apply(context, args); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = args = context = null; - }; - - return debounced; -} - -// Returns the first function passed as an argument to the second, -// allowing you to adjust arguments, run code before and after, and -// conditionally execute the original function. -function wrap(func, wrapper) { - return partial(wrapper, func); -} - -// Returns a negated version of the passed-in predicate. -function negate(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} - -// Returns a function that is the composition of a list of functions, each -// consuming the return value of the function that follows. -function compose() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; -} - -// Returns a function that will only be executed on and after the Nth call. -function after(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - }; -} - -// Returns a function that will only be executed up to (but not including) the -// Nth call. -function before(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (times <= 1) func = null; - return memo; - }; -} - -// Returns a function that will be executed at most one time, no matter how -// often you call it. Useful for lazy initialization. -var once = partial(before, 2); - -// Returns the first key on an object that passes a truth test. -function findKey(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = keys(obj), key; - for (var i = 0, length = _keys.length; i < length; i++) { - key = _keys[i]; - if (predicate(obj[key], key, obj)) return key; - } -} - -// Internal function to generate `_.findIndex` and `_.findLastIndex`. -function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); } - return -1; - }; -} - -// Returns the first index on an array-like that passes a truth test. -var findIndex = createPredicateIndexFinder(1); - -// Returns the last index on an array-like that passes a truth test. -var findLastIndex = createPredicateIndexFinder(-1); - -// Use a comparator function to figure out the smallest index at which -// an object should be inserted so as to maintain order. Uses binary search. -function sortedIndex(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; -} - -// Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. -function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), isNaN$1); - return idx >= 0 ? idx + i : -1; + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - return -1; - }; } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -// Return the position of the first occurrence of an item in an array, -// or -1 if the item is not included in the array. -// If the array is large and already in sort order, pass `true` -// for **isSorted** to use binary search. -var indexOf = createIndexFinder(1, findIndex, sortedIndex); - -// Return the position of the last occurrence of an item in an array, -// or -1 if the item is not included in the array. -var lastIndexOf = createIndexFinder(-1, findLastIndex); - -// Return the first value which passes a truth test. -function find(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? findIndex : findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; -} -// Convenience version of a common use case of `_.find`: getting the first -// object containing specific `key:value` pairs. -function findWhere(obj, attrs) { - return find(obj, matcher(attrs)); -} +/***/ }), -// The cornerstone for collection functions, an `each` -// implementation, aka `forEach`. -// Handles raw objects in addition to array-likes. Treats all -// sparse array-likes as if they were dense. -function each(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var _keys = keys(obj); - for (i = 0, length = _keys.length; i < length; i++) { - iteratee(obj[_keys[i]], _keys[i], obj); - } - } - return obj; -} +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { -// Return the results of applying the iteratee to each element. -function map(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Internal helper to create a reducing function, iterating left or right. -function createReduce(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[_keys ? _keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = _keys ? _keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; +"use strict"; - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -// **Reduce** builds up a single result from a list of values, aka `inject`, -// or `foldl`. -var reduce = createReduce(1); -// The right-associative version of reduce, also known as `foldr`. -var reduceRight = createReduce(-1); - -// Return all the elements that pass a truth test. -function filter(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; -} +/***/ }), -// Return all the elements for which a truth test fails. -function reject(obj, predicate, context) { - return filter(obj, negate(cb(predicate)), context); -} +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { -// Determine whether all of the elements pass a truth test. -function every(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; -} +"use strict"; -// Determine if at least one element in the object passes a truth test. -function some(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; -// Determine if the array or object contains a given item (using `===`). -function contains(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return indexOf(obj, item, fromIndex) >= 0; -} -// Invoke a method (with arguments) on every item in a collection. -var invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (isFunction$1(path)) { - func = path; - } else { - path = toPath(path); - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); -}); +/***/ }), -// Convenience version of a common use case of `_.map`: fetching a property. -function pluck(obj, key) { - return map(obj, property(key)); -} +/***/ 2877: +/***/ ((module) => { -// Convenience version of a common use case of `_.filter`: selecting only -// objects containing specific `key:value` pairs. -function where(obj, attrs) { - return filter(obj, matcher(attrs)); -} +module.exports = eval("require")("encoding"); -// Return the maximum element (or element-based computation). -function max(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} -// Return the minimum element (or element-based computation). -function min(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || (computed === Infinity && result === Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} +/***/ }), -// Safely create a real, live array from anything iterable. -var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; -function toArray(obj) { - if (!obj) return []; - if (isArray(obj)) return slice.call(obj); - if (isString(obj)) { - // Keep surrogate pair characters together. - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return map(obj, identity); - return values(obj); -} +/***/ 9491: +/***/ ((module) => { -// Sample **n** random values from a collection using the modern version of the -// [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). -// If **n** is not specified, returns a single random element. -// The internal `guard` argument allows it to work with `_.map`. -function sample(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = values(obj); - return obj[random(obj.length - 1)]; - } - var sample = toArray(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); -} +"use strict"; +module.exports = require("assert"); -// Shuffle a collection. -function shuffle(obj) { - return sample(obj, Infinity); -} +/***/ }), -// Sort the object's values by a criterion produced by an iteratee. -function sortBy(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return pluck(map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); -} - -// An internal function used for aggregate "group by" operations. -function group(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; -} +/***/ 6113: +/***/ ((module) => { -// Groups the object's values by a criterion. Pass either a string attribute -// to group by, or a function that returns the criterion. -var groupBy = group(function(result, value, key) { - if (has$1(result, key)) result[key].push(value); else result[key] = [value]; -}); +"use strict"; +module.exports = require("crypto"); -// Indexes the object's values by a criterion, similar to `_.groupBy`, but for -// when you know that your index values will be unique. -var indexBy = group(function(result, value, key) { - result[key] = value; -}); +/***/ }), -// Counts instances of an object that group by a certain criterion. Pass -// either a string attribute to count by, or a function that returns the -// criterion. -var countBy = group(function(result, value, key) { - if (has$1(result, key)) result[key]++; else result[key] = 1; -}); +/***/ 2361: +/***/ ((module) => { -// Split a collection into two arrays: one whose elements all pass the given -// truth test, and one whose elements all do not pass the truth test. -var partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); -}, true); +"use strict"; +module.exports = require("events"); -// Return the number of elements in a collection. -function size(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : keys(obj).length; -} +/***/ }), -// Internal `_.pick` helper function to determine whether `key` is an enumerable -// property name of `obj`. -function keyInObj(value, key, obj) { - return key in obj; -} +/***/ 7147: +/***/ ((module) => { -// Return a copy of the object only containing the allowed properties. -var pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (isFunction$1(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten$1(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; -}); +"use strict"; +module.exports = require("fs"); -// Return a copy of the object without the disallowed properties. -var omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (isFunction$1(iteratee)) { - iteratee = negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = map(flatten$1(keys, false, false), String); - iteratee = function(value, key) { - return !contains(keys, key); - }; - } - return pick(obj, iteratee, context); -}); +/***/ }), -// Returns everything but the last entry of the array. Especially useful on -// the arguments object. Passing **n** will return all the values in -// the array, excluding the last N. -function initial(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); -} +/***/ 3685: +/***/ ((module) => { -// Get the first element of an array. Passing **n** will return the first N -// values in the array. The **guard** check allows it to work with `_.map`. -function first(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[0]; - return initial(array, array.length - n); -} +"use strict"; +module.exports = require("http"); -// Returns everything but the first entry of the `array`. Especially useful on -// the `arguments` object. Passing an **n** will return the rest N values in the -// `array`. -function rest(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); -} +/***/ }), -// Get the last element of an array. Passing **n** will return the last N -// values in the array. -function last(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return rest(array, Math.max(0, array.length - n)); -} +/***/ 5687: +/***/ ((module) => { -// Trim out all falsy values from an array. -function compact(array) { - return filter(array, Boolean); -} +"use strict"; +module.exports = require("https"); -// Flatten out an array, either recursively (by default), or up to `depth`. -// Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. -function flatten(array, depth) { - return flatten$1(array, depth, false); -} +/***/ }), -// Take the difference between one array and a number of other arrays. -// Only the elements present in just the first array will remain. -var difference = restArguments(function(array, rest) { - rest = flatten$1(rest, true, true); - return filter(array, function(value){ - return !contains(rest, value); - }); -}); +/***/ 1808: +/***/ ((module) => { -// Return a version of the array that does not contain the specified value(s). -var without = restArguments(function(array, otherArrays) { - return difference(array, otherArrays); -}); +"use strict"; +module.exports = require("net"); -// Produce a duplicate-free version of the array. If the array has already -// been sorted, you have the option of using a faster algorithm. -// The faster algorithm will not work with an iteratee if the iteratee -// is not a one-to-one function, so providing an iteratee will disable -// the faster algorithm. -function uniq(array, isSorted, iteratee, context) { - if (!isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!contains(result, value)) { - result.push(value); - } - } - return result; -} +/***/ }), -// Produce an array that contains the union: each distinct element from all of -// the passed-in arrays. -var union = restArguments(function(arrays) { - return uniq(flatten$1(arrays, true, true)); -}); +/***/ 2037: +/***/ ((module) => { -// Produce an array that contains every item shared between all the -// passed-in arrays. -function intersection(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; -} +"use strict"; +module.exports = require("os"); -// Complement of zip. Unzip accepts an array of arrays and groups -// each array's elements on shared indices. -function unzip(array) { - var length = (array && max(array, getLength).length) || 0; - var result = Array(length); +/***/ }), - for (var index = 0; index < length; index++) { - result[index] = pluck(array, index); - } - return result; -} +/***/ 1017: +/***/ ((module) => { -// Zip together multiple lists into a single array -- elements that share -// an index go together. -var zip = restArguments(unzip); +"use strict"; +module.exports = require("path"); -// Converts lists into objects. Pass either a single array of `[key, value]` -// pairs, or two parallel arrays of the same length -- one of keys, and one of -// the corresponding values. Passing by pairs is the reverse of `_.pairs`. -function object(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; -} +/***/ }), -// Generate an integer Array containing an arithmetic progression. A port of -// the native Python `range()` function. See -// [the Python documentation](https://docs.python.org/library/functions.html#range). -function range(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } +/***/ 5477: +/***/ ((module) => { - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); +"use strict"; +module.exports = require("punycode"); - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } +/***/ }), - return range; -} +/***/ 2781: +/***/ ((module) => { -// Chunk a single array into multiple arrays, each containing `count` or fewer -// items. -function chunk(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; -} +"use strict"; +module.exports = require("stream"); -// Helper function to continue chaining intermediate results. -function chainResult(instance, obj) { - return instance._chain ? _$1(obj).chain() : obj; -} +/***/ }), -// Add your own custom functions to the Underscore object. -function mixin(obj) { - each(functions(obj), function(name) { - var func = _$1[name] = obj[name]; - _$1.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_$1, args)); - }; - }); - return _$1; -} - -// Add all mutator `Array` functions to the wrapper. -each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) { - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) { - delete obj[0]; - } - } - return chainResult(this, obj); - }; -}); +/***/ 4404: +/***/ ((module) => { -// Add all accessor `Array` functions to the wrapper. -each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) obj = method.apply(obj, arguments); - return chainResult(this, obj); - }; -}); +"use strict"; +module.exports = require("tls"); -// Named Exports - -var allExports = { - __proto__: null, - VERSION: VERSION, - restArguments: restArguments, - isObject: isObject, - isNull: isNull, - isUndefined: isUndefined, - isBoolean: isBoolean, - isElement: isElement, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isRegExp: isRegExp, - isError: isError, - isSymbol: isSymbol, - isArrayBuffer: isArrayBuffer, - isDataView: isDataView$1, - isArray: isArray, - isFunction: isFunction$1, - isArguments: isArguments$1, - isFinite: isFinite$1, - isNaN: isNaN$1, - isTypedArray: isTypedArray$1, - isEmpty: isEmpty, - isMatch: isMatch, - isEqual: isEqual, - isMap: isMap, - isWeakMap: isWeakMap, - isSet: isSet, - isWeakSet: isWeakSet, - keys: keys, - allKeys: allKeys, - values: values, - pairs: pairs, - invert: invert, - functions: functions, - methods: functions, - extend: extend, - extendOwn: extendOwn, - assign: extendOwn, - defaults: defaults, - create: create, - clone: clone, - tap: tap, - get: get, - has: has, - mapObject: mapObject, - identity: identity, - constant: constant, - noop: noop, - toPath: toPath$1, - property: property, - propertyOf: propertyOf, - matcher: matcher, - matches: matcher, - times: times, - random: random, - now: now, - escape: _escape, - unescape: _unescape, - templateSettings: templateSettings, - template: template, - result: result, - uniqueId: uniqueId, - chain: chain, - iteratee: iteratee, - partial: partial, - bind: bind, - bindAll: bindAll, - memoize: memoize, - delay: delay, - defer: defer, - throttle: throttle, - debounce: debounce, - wrap: wrap, - negate: negate, - compose: compose, - after: after, - before: before, - once: once, - findKey: findKey, - findIndex: findIndex, - findLastIndex: findLastIndex, - sortedIndex: sortedIndex, - indexOf: indexOf, - lastIndexOf: lastIndexOf, - find: find, - detect: find, - findWhere: findWhere, - each: each, - forEach: each, - map: map, - collect: map, - reduce: reduce, - foldl: reduce, - inject: reduce, - reduceRight: reduceRight, - foldr: reduceRight, - filter: filter, - select: filter, - reject: reject, - every: every, - all: every, - some: some, - any: some, - contains: contains, - includes: contains, - include: contains, - invoke: invoke, - pluck: pluck, - where: where, - max: max, - min: min, - shuffle: shuffle, - sample: sample, - sortBy: sortBy, - groupBy: groupBy, - indexBy: indexBy, - countBy: countBy, - partition: partition, - toArray: toArray, - size: size, - pick: pick, - omit: omit, - first: first, - head: first, - take: first, - initial: initial, - last: last, - rest: rest, - tail: rest, - drop: rest, - compact: compact, - flatten: flatten, - without: without, - uniq: uniq, - unique: uniq, - union: union, - intersection: intersection, - difference: difference, - unzip: unzip, - transpose: unzip, - zip: zip, - object: object, - range: range, - chunk: chunk, - mixin: mixin, - 'default': _$1 -}; +/***/ }), -// Default Export - -// Add all of the Underscore functions to the wrapper object. -var _ = mixin(allExports); -// Legacy Node.js API. -_._ = _; - -exports.VERSION = VERSION; -exports._ = _; -exports._escape = _escape; -exports._unescape = _unescape; -exports.after = after; -exports.allKeys = allKeys; -exports.before = before; -exports.bind = bind; -exports.bindAll = bindAll; -exports.chain = chain; -exports.chunk = chunk; -exports.clone = clone; -exports.compact = compact; -exports.compose = compose; -exports.constant = constant; -exports.contains = contains; -exports.countBy = countBy; -exports.create = create; -exports.debounce = debounce; -exports.defaults = defaults; -exports.defer = defer; -exports.delay = delay; -exports.difference = difference; -exports.each = each; -exports.every = every; -exports.extend = extend; -exports.extendOwn = extendOwn; -exports.filter = filter; -exports.find = find; -exports.findIndex = findIndex; -exports.findKey = findKey; -exports.findLastIndex = findLastIndex; -exports.findWhere = findWhere; -exports.first = first; -exports.flatten = flatten; -exports.functions = functions; -exports.get = get; -exports.groupBy = groupBy; -exports.has = has; -exports.identity = identity; -exports.indexBy = indexBy; -exports.indexOf = indexOf; -exports.initial = initial; -exports.intersection = intersection; -exports.invert = invert; -exports.invoke = invoke; -exports.isArguments = isArguments$1; -exports.isArray = isArray; -exports.isArrayBuffer = isArrayBuffer; -exports.isBoolean = isBoolean; -exports.isDataView = isDataView$1; -exports.isDate = isDate; -exports.isElement = isElement; -exports.isEmpty = isEmpty; -exports.isEqual = isEqual; -exports.isError = isError; -exports.isFinite = isFinite$1; -exports.isFunction = isFunction$1; -exports.isMap = isMap; -exports.isMatch = isMatch; -exports.isNaN = isNaN$1; -exports.isNull = isNull; -exports.isNumber = isNumber; -exports.isObject = isObject; -exports.isRegExp = isRegExp; -exports.isSet = isSet; -exports.isString = isString; -exports.isSymbol = isSymbol; -exports.isTypedArray = isTypedArray$1; -exports.isUndefined = isUndefined; -exports.isWeakMap = isWeakMap; -exports.isWeakSet = isWeakSet; -exports.iteratee = iteratee; -exports.keys = keys; -exports.last = last; -exports.lastIndexOf = lastIndexOf; -exports.map = map; -exports.mapObject = mapObject; -exports.matcher = matcher; -exports.max = max; -exports.memoize = memoize; -exports.min = min; -exports.mixin = mixin; -exports.negate = negate; -exports.noop = noop; -exports.now = now; -exports.object = object; -exports.omit = omit; -exports.once = once; -exports.pairs = pairs; -exports.partial = partial; -exports.partition = partition; -exports.pick = pick; -exports.pluck = pluck; -exports.property = property; -exports.propertyOf = propertyOf; -exports.random = random; -exports.range = range; -exports.reduce = reduce; -exports.reduceRight = reduceRight; -exports.reject = reject; -exports.rest = rest; -exports.restArguments = restArguments; -exports.result = result; -exports.sample = sample; -exports.shuffle = shuffle; -exports.size = size; -exports.some = some; -exports.sortBy = sortBy; -exports.sortedIndex = sortedIndex; -exports.tap = tap; -exports.template = template; -exports.templateSettings = templateSettings; -exports.throttle = throttle; -exports.times = times; -exports.toArray = toArray; -exports.toPath = toPath$1; -exports.union = union; -exports.uniq = uniq; -exports.uniqueId = uniqueId; -exports.unzip = unzip; -exports.values = values; -exports.where = where; -exports.without = without; -exports.wrap = wrap; -exports.zip = zip; -//# sourceMappingURL=underscore-node-f.cjs.map +/***/ 7310: +/***/ ((module) => { +"use strict"; +module.exports = require("url"); /***/ }), -/***/ 5067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -var underscoreNodeF = __nccwpck_require__(6717); +/***/ 3837: +/***/ ((module) => { +"use strict"; +module.exports = require("util"); +/***/ }), -module.exports = underscoreNodeF._; -//# sourceMappingURL=underscore-node.cjs.map +/***/ 9796: +/***/ ((module) => { +"use strict"; +module.exports = require("zlib"); /***/ }), @@ -16009,7 +12156,7 @@ var __webpack_exports__ = {}; (() => { const core = __nccwpck_require__(2186); const ActionUtils = __nccwpck_require__(970); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); // Parse the stringified JSON array of PR numbers, and cast each from String -> Number const PRList = ActionUtils.getJSONInput('PR_LIST', {required: true}); diff --git a/.github/actions/javascript/isStagingDeployLocked/index.js b/.github/actions/javascript/isStagingDeployLocked/index.js index 8124c5795a5a..c5afdab0b078 100644 --- a/.github/actions/javascript/isStagingDeployLocked/index.js +++ b/.github/actions/javascript/isStagingDeployLocked/index.js @@ -9,7 +9,7 @@ const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); const run = function () { return GithubUtils.getStagingDeployCash() @@ -58,784 +58,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4806,3919 +4260,2309 @@ const Endpoints = { }], renameBranch: ["POST /repos/{owner}/{repo}/branches/{branch}/rename"], replaceAllTopics: ["PUT /repos/{owner}/{repo}/topics"], - requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], - setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], - setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { - mapToData: "apps" - }], - setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { - mapToData: "contexts" - }], - setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { - mapToData: "teams" - }], - setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { - mapToData: "users" - }], - testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], - transfer: ["POST /repos/{owner}/{repo}/transfer"], - update: ["PATCH /repos/{owner}/{repo}"], - updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], - updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], - updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], - updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], - updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], + setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], + transfer: ["POST /repos/{owner}/{repo}/transfer"], + update: ["PATCH /repos/{owner}/{repo}"], + updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], + updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], + updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], + updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; + +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +"use strict"; -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = Hash; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; -module.exports = ListCache; + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ }), + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + const req = state.global.key(state.id).schedule(jobOptions, request, options); -module.exports = Map; + if (isGraphQL) { + const res = await req; + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -/***/ }), + return req; +} -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +function routeMatcher(paths) { + // EXAMPLE. For the following paths: -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -module.exports = MapCache; + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ + return new RegExp(regex, "i"); +} -/***/ }), +// @ts-expect-error -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -var root = __nccwpck_require__(9882); +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -/** Built-in value references. */ -var Symbol = root.Symbol; +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -module.exports = Symbol; + if (!enabled) { + return {}; + } + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 4356: -/***/ ((module) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling - while (++index < length) { - result[index] = iteratee(array[index], index, array); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); } - return result; -} -module.exports = arrayMap; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -/***/ }), + events.on("rate-limit", state.onRateLimit); // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -var eq = __nccwpck_require__(1901); + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } + + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } + + return {}; + }(); + + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; } - } - return -1; + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = assocIndexOf; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5758: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) - var index = 0, - length = path.length; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) } -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +function HookCollection () { + var state = { + registry: {} + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return hook +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return HookCollection() } -module.exports = baseIsNative; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +/***/ 5549: +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +module.exports = addHook; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} -module.exports = baseToString; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4670: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = register; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!options) { + options = {}; + } -var root = __nccwpck_require__(9882); + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -module.exports = coreJsData; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} /***/ }), -/***/ 2085: +/***/ 6819: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - +module.exports = removeHook; -/***/ }), +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + if (index === -1) { + return; + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + state.registry[name].splice(index, 1); } -module.exports = getNative; - /***/ }), -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13403,230 +11247,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/index.js b/.github/actions/javascript/markPullRequestsAsDeployed/index.js index 36cd0aaefe4a..13bbfe30b05f 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/index.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/index.js @@ -4,155 +4,6 @@ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 2759: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const core = __nccwpck_require__(2186); -const {context} = __nccwpck_require__(5438); -const CONST = __nccwpck_require__(4097); -const ActionUtils = __nccwpck_require__(970); -const GithubUtils = __nccwpck_require__(7999); - -/** - * Return a nicely formatted message for the table based on the result of the GitHub action job - * - * @param {String} platformResult - * @returns {String} - */ -function getDeployTableMessage(platformResult) { - switch (platformResult) { - case 'success': - return `${platformResult} ✅`; - case 'cancelled': - return `${platformResult} 🔪`; - case 'skipped': - return `${platformResult} 🚫`; - case 'failure': - default: - return `${platformResult} ❌`; - } -} - -/** - * Comment Single PR - * - * @param {Number} PR - * @param {String} message - * @returns {Promise} - */ -async function commentPR(PR, message) { - try { - await GithubUtils.createComment(context.repo.repo, PR, message); - console.log(`Comment created on #${PR} successfully 🎉`); - } catch (err) { - console.log(`Unable to write comment on #${PR} 😞`); - core.setFailed(err.message); - } -} - -const workflowURL = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; - -async function run() { - const prList = _.map(ActionUtils.getJSONInput('PR_LIST', {required: true}), (num) => Number.parseInt(num, 10)); - const isProd = ActionUtils.getJSONInput('IS_PRODUCTION_DEPLOY', {required: true}); - const version = core.getInput('DEPLOY_VERSION', {required: true}); - - const androidResult = getDeployTableMessage(core.getInput('ANDROID', {required: true})); - const desktopResult = getDeployTableMessage(core.getInput('DESKTOP', {required: true})); - const iOSResult = getDeployTableMessage(core.getInput('IOS', {required: true})); - const webResult = getDeployTableMessage(core.getInput('WEB', {required: true})); - - /** - * @param {String} deployer - * @param {String} deployVerb - * @param {String} prTitle - * @returns {String} - */ - function getDeployMessage(deployer, deployVerb, prTitle) { - let message = `🚀 [${deployVerb}](${workflowURL}) to ${isProd ? 'production' : 'staging'}`; - message += ` by https://github.com/${deployer} in version: ${version} 🚀`; - message += `\n\nplatform | result\n---|---\n🤖 android 🤖|${androidResult}\n🖥 desktop 🖥|${desktopResult}`; - message += `\n🍎 iOS 🍎|${iOSResult}\n🕸 web 🕸|${webResult}`; - - if (deployVerb === 'Cherry-picked' && !/no ?qa/gi.test(prTitle)) { - // eslint-disable-next-line max-len - message += - '\n\n@Expensify/applauseleads please QA this PR and check it off on the [deploy checklist](https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3AStagingDeployCash) if it passes.'; - } - - return message; - } - - if (isProd) { - // Find the previous deploy checklist - const {data: deployChecklists} = await GithubUtils.octokit.issues.listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'closed', - }); - const previousChecklistID = _.first(deployChecklists).number; - - // who closed the last deploy checklist? - const deployer = await GithubUtils.getActorWhoClosedIssue(previousChecklistID); - - // Create comment on each pull request (one at a time to avoid throttling issues) - const deployMessage = getDeployMessage(deployer, 'Deployed'); - for (const pr of prList) { - await commentPR(pr, deployMessage); - } - return; - } - - // First find out if this is a normal staging deploy or a CP by looking at the commit message on the tag - const {data: recentTags} = await GithubUtils.octokit.repos.listTags({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }); - const currentTag = _.find(recentTags, (tag) => tag.name === version); - if (!currentTag) { - const err = `Could not find tag matching ${version}`; - console.error(err); - core.setFailed(err); - return; - } - const {data: commit} = await GithubUtils.octokit.git.getCommit({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - commit_sha: currentTag.commit.sha, - }); - const isCP = /[\S\s]*\(cherry picked from commit .*\)/.test(commit.message); - - for (const prNumber of prList) { - /* - * Determine who the deployer for the PR is. The "deployer" for staging deploys is: - * 1. For regular staging deploys, the person who merged the PR. - * 2. For CPs, the person who committed the cherry-picked commit (not necessarily the author of the commit). - */ - const {data: pr} = await GithubUtils.octokit.pulls.get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: prNumber, - }); - const deployer = isCP ? commit.committer.name : pr.merged_by.login; - - const title = pr.title; - const deployMessage = getDeployMessage(deployer, isCP ? 'Cherry-picked' : 'Deployed', title); - await commentPR(prNumber, deployMessage); - } -} - -if (require.main === require.cache[eval('__filename')]) { - run(); -} - -module.exports = run; - - -/***/ }), - /***/ 970: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { @@ -223,655 +74,109 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.rest; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.graphql; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; - } - this.initOctokit(); - return this.internalOctokit.paginate; - } +/***/ }), - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } - - return this.getStagingDeployCashData(data[0]); - }); - } - - /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} - */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - - /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] - */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); - } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); - } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); - } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; +"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; @@ -7322,4152 +6627,2542 @@ exports.isPlainObject = isPlainObject; /***/ }), -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +/***/ 467: +/***/ ((module, exports, __nccwpck_require__) => { -module.exports = Hash; +"use strict"; -/***/ }), +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +var Stream = _interopDefault(__nccwpck_require__(2781)); +var http = _interopDefault(__nccwpck_require__(3685)); +var Url = _interopDefault(__nccwpck_require__(7310)); +var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); +var https = _interopDefault(__nccwpck_require__(5687)); +var zlib = _interopDefault(__nccwpck_require__(9796)); -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); -module.exports = ListCache; +class Blob { + constructor() { + this[TYPE] = ''; + const blobParts = arguments[0]; + const options = arguments[1]; -/***/ }), + const buffers = []; + let size = 0; -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + this[BUFFER] = Buffer.concat(buffers); -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; -module.exports = Map; + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} -/***/ }), +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ /** - * Creates a map cache object to store key-value pairs. + * Create FetchError instance * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; } -} -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} -module.exports = MapCache; - - -/***/ }), - -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Built-in value references. */ -var Symbol = root.Symbol; - -module.exports = Symbol; +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; +let convert; +try { + convert = (__nccwpck_require__(2877).convert); +} catch (e) {} -/***/ }), +const INTERNALS = Symbol('Body internals'); -/***/ 4356: -/***/ ((module) => { +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} - -module.exports = arrayMap; - +function Body(body) { + var _this = this; -/***/ }), + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; -var eq = __nccwpck_require__(1901); + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } } -module.exports = assocIndexOf; - - -/***/ }), - -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); + get bodyUsed() { + return this[INTERNALS].disturbed; + }, -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, - var index = 0, - length = path.length; + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; -module.exports = baseGet; + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, -/***/ }), + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; /** - * The base implementation of `getTag` without fallbacks for buggy environments. + * Consume and convert an entire Body to a Buffer. * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); -} - -module.exports = baseGetTag; +function consumeBody() { + var _this4 = this; + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } -/***/ }), + this[INTERNALS].disturbed = true; -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); + let body = this.body; -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; + // body is blob + if (isBlob(body)) { + body = body.stream(); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return new Body.Promise(function (resolve, reject) { + let resTimeout; -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } -module.exports = baseIsNative; + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } -/***/ }), - -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + accumBytes += chunk.length; + accum.push(chunk); + }); -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + body.on('end', function () { + if (abort) { + return; + } -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; + clearTimeout(resTimeout); -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); } -module.exports = baseToString; - - -/***/ }), - -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); - /** - * Casts `value` to a path array if it's not one. + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String */ -function castPath(value, object) { - if (isArray(value)) { - return value; - } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -module.exports = coreJsData; +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; -/***/ }), + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } -/***/ 2085: -/***/ ((module) => { + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + // html5 + if (!res && str) { + res = / { + // found charset + if (res) { + charset = res.pop(); -var isKeyable = __nccwpck_require__(3308); + // prevent decode issues when sites use incorrect encoding + // ref: https://hsivonen.fi/encoding-menu/ + if (charset === 'gb2312' || charset === 'gbk') { + charset = 'gb18030'; + } + } -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; + // turn raw buffers into a single utf-8 buffer + return convert(buffer, 'UTF-8', charset).toString(); } -module.exports = getMapData; - - -/***/ }), - -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); - /** - * Gets the native function at `key` of `object`. + * Detect a URLSearchParams object + * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. + * @param Object obj Object to detect by type or brand + * @return String */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -module.exports = getNative; - - -/***/ }), - -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; +function isURLSearchParams(obj) { + // Duck-typing as a necessary condition. + if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { + return false; + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + // Brand-checking and more duck-typing as optional condition. + return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; +} /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. + * Check if `obj` is a W3C `Blob` object (which `File` inherits from) + * @param {*} obj + * @return {boolean} */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; +function isBlob(obj) { + return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); +} /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * Clone body given Res/Req instance * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. + * @param Mixed instance Response or Request instance + * @return Mixed */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} - -module.exports = getRawTag; +function clone(instance) { + let p1, p2; + let body = instance.body; + // don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } -/***/ }), + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof Stream && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } -/***/ 3542: -/***/ ((module) => { + return body; +} /** - * Gets the value at `key` of `object`. + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract + * + * This function assumes that instance.body is present. * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. + * @param Mixed instance Any options.body input */ -function getValue(object, key) { - return object == null ? undefined : object[key]; +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof Stream) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } } -module.exports = getValue; - - -/***/ }), - -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - /** - * Removes all key-value entries from the hash. + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes * - * @private - * @name clear - * @memberOf Hash + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} - -module.exports = hashClear; - +function getTotalBytes(instance) { + const body = instance.body; -/***/ }), -/***/ 712: -/***/ ((module) => { + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} /** - * Removes `key` and its value from the hash. + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @param Body instance Instance of Body + * @return Void */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} - -module.exports = hashDelete; - - -/***/ }), - -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; +function writeToStream(dest, instance) { + const body = instance.body; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } } -module.exports = hashGet; - - -/***/ }), - -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +// expose Promise +Body.Promise = global.Promise; /** - * Checks if a hash value for `key` exists. + * headers.js * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * Headers class offers convenient helpers */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} - -module.exports = hashHas; - - -/***/ }), - -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } } -module.exports = hashSet; - - -/***/ }), - -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); - -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } } -module.exports = isKey; - - -/***/ }), - -/***/ 3308: -/***/ ((module) => { - /** - * Checks if `value` is suitable for use as unique object key. + * Find the key in the map object given a header name. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -module.exports = isKeyable; - - -/***/ }), - -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var coreJsData = __nccwpck_require__(8380); - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** - * Checks if `func` has its source masked. + * Returns undefined if not found. * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. + * @param String name Header name + * @return String|Undefined */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; } -module.exports = isMasked; - - -/***/ }), +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; -/***/ 9792: -/***/ ((module) => { + this[MAP] = Object.create(null); -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); -module.exports = listCacheClear; + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + return; + } -/***/ }), + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } -var assocIndexOf = __nccwpck_require__(6752); + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } -/** Built-in value references. */ -var splice = arrayProto.splice; + return this[MAP][key].join(', '); + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; -module.exports = listCacheDelete; + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } -/***/ }), + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -module.exports = listCacheGet; + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } -/***/ }), + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } -var assocIndexOf = __nccwpck_require__(6752); + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } } +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; -module.exports = listCacheHas; - +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); -/***/ }), +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; -var assocIndexOf = __nccwpck_require__(6752); + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); +const INTERNAL = Symbol('internal'); - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; } -module.exports = listCacheSet; +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } -/***/ }), + this[INTERNAL].index = index + 1; -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); /** - * Removes all key-value entries from the map. + * Export the Headers object in a form that Node.js can consume. * - * @private - * @name clear - * @memberOf MapCache + * @param Headers headers + * @return Object */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -module.exports = mapCacheClear; - - -/***/ }), +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } -var getMapData = __nccwpck_require__(9980); + return obj; +} /** - * Removes `key` and its value from the map. + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @param Object obj Object of headers + * @return Headers */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; } -module.exports = mapCacheDelete; - - -/***/ }), - -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const INTERNALS$1 = Symbol('Response internals'); -var getMapData = __nccwpck_require__(9980); +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; /** - * Gets the map value for `key`. + * Response class * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -module.exports = mapCacheGet; +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Body.call(this, body, opts); -/***/ }), + const status = opts.status || 200; + const headers = new Headers(opts.headers); -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } -var getMapData = __nccwpck_require__(9980); + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + get url() { + return this[INTERNALS$1].url || ''; + } -module.exports = mapCacheHas; + get status() { + return this[INTERNALS$1].status; + } + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } -/***/ }), + get redirected() { + return this[INTERNALS$1].counter > 0; + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getMapData = __nccwpck_require__(9980); + get statusText() { + return this[INTERNALS$1].statusText; + } -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + get headers() { + return this[INTERNALS$1].headers; + } - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } } -module.exports = mapCacheSet; - +Body.mixIn(Response.prototype); -/***/ }), +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); -var memoize = __nccwpck_require__(9885); +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; /** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * Wrapper around `new URL` to handle arbitrary URLs * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. + * @param {string} urlStr + * @return {void} */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } - var cache = result.cache; - return result; + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); } -module.exports = memoizeCapped; - - -/***/ }), - -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479); - -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); - -module.exports = nativeCreate; - - -/***/ }), - -/***/ 4200: -/***/ ((module) => { - -/** Used for built-in method references. */ -var objectProto = Object.prototype; +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean */ -var nativeObjectToString = objectProto.toString; +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} /** - * Converts `value` to a string using `Object.prototype.toString`. + * Request class * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void */ -function objectToString(value) { - return nativeObjectToString.call(value); -} +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; -module.exports = objectToString; + let parsedURL; + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } -/***/ }), + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } -var freeGlobal = __nccwpck_require__(2085); + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + const headers = new Headers(init.headers || input.headers || {}); -module.exports = root; + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; -/***/ }), + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; -var memoizeCapped = __nccwpck_require__(9422); + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + get method() { + return this[INTERNALS$2].method; + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + get headers() { + return this[INTERNALS$2].headers; + } -module.exports = stringToPath; + get redirect() { + return this[INTERNALS$2].redirect; + } + get signal() { + return this[INTERNALS$2].signal; + } -/***/ }), + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +Body.mixIn(Request.prototype); -var isSymbol = __nccwpck_require__(6403); +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); /** - * Converts `value` to a string key if it's not a string or symbol. + * Convert a Request to Node.js http request options. * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. + * @param Request A Request instance + * @return Object The options object to be passed to http.request */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} - -module.exports = toKey; +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } -/***/ }), + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } -/***/ 6928: -/***/ ((module) => { + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } -module.exports = toSource; + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } -/***/ }), + if (!headers.has('Connection') && !agent) { + headers.set('Connection', 'close'); + } -/***/ 1901: -/***/ ((module) => { + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); } -module.exports = eq; - - -/***/ }), - -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseGet = __nccwpck_require__(5758); - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 + * abort-error.js * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' + * AbortError interface for cancelled requests */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} - -module.exports = get; - - -/***/ }), - -/***/ 4869: -/***/ ((module) => { /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false + * Create AbortError instance * - * _.isArray(_.noop); - * // => false + * @param String message Error message for human + * @return AbortError */ -var isArray = Array.isArray; +function AbortError(message) { + Error.call(this, message); -module.exports = isArray; + this.type = 'aborted'; + this.message = message; + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} -/***/ }), +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true + * Fetch function * - * _.isFunction(/abc/); - * // => false + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} +function fetch(url, opts) { -module.exports = isFunction; + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + Body.Promise = fetch.Promise; -/***/ }), + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); -/***/ 3334: -/***/ ((module) => { + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + let response = null; -module.exports = isObject; + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + request.body.destroy(error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + if (signal && signal.aborted) { + abort(); + return; + } -/***/ }), + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; -/***/ 5926: -/***/ ((module) => { + // send request + const req = send(options); + let reqTimeout; -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } -module.exports = isObjectLike; + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } -/***/ }), + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + finalize(); + }); -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + req.on('response', function (res) { + clearTimeout(reqTimeout); -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + const headers = createHeadersLenient(res.headers); -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); -} + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } -module.exports = isSymbol; + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } -/***/ }), + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!isDomainOrSubdomain(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } -var MapCache = __nccwpck_require__(938); + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; -} + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); -// Expose `MapCache`. -memoize.Cache = MapCache; + // HTTP-network fetch step 12.1.1.4: handle content codings -module.exports = memoize; + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; -/***/ }), + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } -var baseToString = __nccwpck_require__(6792); + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + writeToStream(req, request); + }); +} /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' + * Redirect code matching * - * _.toString([1, 2, 3]); - * // => '1,2,3' + * @param Number code Status code + * @return Boolean */ -function toString(value) { - return value == null ? '' : baseToString(value); -} +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; -module.exports = toString; +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports["default"] = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; /***/ }), -/***/ 467: -/***/ ((module, exports, __nccwpck_require__) => { +/***/ 2299: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var Stream = _interopDefault(__nccwpck_require__(2781)); -var http = _interopDefault(__nccwpck_require__(3685)); -var Url = _interopDefault(__nccwpck_require__(7310)); -var whatwgUrl = _interopDefault(__nccwpck_require__(3323)); -var https = _interopDefault(__nccwpck_require__(5687)); -var zlib = _interopDefault(__nccwpck_require__(9796)); +var punycode = __nccwpck_require__(5477); +var mappingTable = __nccwpck_require__(1907); -// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js +var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 +}; -// fix for "Readable" isn't a named export issue -const Readable = Stream.Readable; +function normalize(str) { // fix bug in v8 + return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); +} -const BUFFER = Symbol('buffer'); -const TYPE = Symbol('type'); +function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; -class Blob { - constructor() { - this[TYPE] = ''; + while (start <= end) { + var mid = Math.floor((start + end) / 2); - const blobParts = arguments[0]; - const options = arguments[1]; + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } - const buffers = []; - let size = 0; + return null; +} - if (blobParts) { - const a = blobParts; - const length = Number(a.length); - for (let i = 0; i < length; i++) { - const element = a[i]; - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = element[BUFFER]; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); - } - size += buffer.length; - buffers.push(buffer); - } - } +var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; - this[BUFFER] = Buffer.concat(buffers); +function countSymbols(string) { + return string + // replace every surrogate pair with a BMP symbol + .replace(regexAstralSymbols, '_') + // then get the length + .length; +} - let type = options && options.type !== undefined && String(options.type).toLowerCase(); - if (type && !/[^\u0020-\u007E]/.test(type)) { - this[TYPE] = type; - } - } - get size() { - return this[BUFFER].length; - } - get type() { - return this[TYPE]; - } - text() { - return Promise.resolve(this[BUFFER].toString()); - } - arrayBuffer() { - const buf = this[BUFFER]; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); - } - stream() { - const readable = new Readable(); - readable._read = function () {}; - readable.push(this[BUFFER]); - readable.push(null); - return readable; - } - toString() { - return '[object Blob]'; - } - slice() { - const size = this.size; +function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; - const start = arguments[0]; - const end = arguments[1]; - let relativeStart, relativeEnd; - if (start === undefined) { - relativeStart = 0; - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); - } else { - relativeStart = Math.min(start, size); - } - if (end === undefined) { - relativeEnd = size; - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); - } else { - relativeEnd = Math.min(end, size); - } - const span = Math.max(relativeEnd - relativeStart, 0); + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); - const buffer = this[BUFFER]; - const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); - const blob = new Blob([], { type: arguments[2] }); - blob[BUFFER] = slicedBuffer; - return blob; - } + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } + + processed += String.fromCodePoint(codePoint); + break; + } + } + + return { + string: processed, + error: hasError + }; } -Object.defineProperties(Blob.prototype, { - size: { enumerable: true }, - type: { enumerable: true }, - slice: { enumerable: true } -}); +var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); +function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } -/** - * fetch-error.js - * - * FetchError interface for operational errors - */ + var error = false; -/** - * Create FetchError instance - * - * @param String message Error message for human - * @param String type Error type for machine - * @param String systemError For Node.js system error - * @return FetchError - */ -function FetchError(message, type, systemError) { - Error.call(this, message); + if (normalize(label) !== label || + (label[3] === "-" && label[4] === "-") || + label[0] === "-" || label[label.length - 1] === "-" || + label.indexOf(".") !== -1 || + label.search(combiningMarksRegex) === 0) { + error = true; + } - this.message = message; - this.type = type; + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || + (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && + status[1] !== "valid" && status[1] !== "deviation")) { + error = true; + break; + } + } - // when err.type is `system`, err.code contains system error code - if (systemError) { - this.code = this.errno = systemError.code; + return { + label: label, + error: error + }; +} + +function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); + + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch(e) { + result.error = true; + } } - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); + return { + string: labels.join("."), + error: result.error + }; } -FetchError.prototype = Object.create(Error.prototype); -FetchError.prototype.constructor = FetchError; -FetchError.prototype.name = 'FetchError'; +module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch(e) { + result.error = true; + return l; + } + }); -let convert; -try { - convert = (__nccwpck_require__(2877).convert); -} catch (e) {} + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } -const INTERNALS = Symbol('Body internals'); + for (var i=0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } -// fix an issue where "PassThrough" isn't a named export for node <10 -const PassThrough = Stream.PassThrough; + if (result.error) return null; + return labels.join("."); +}; -/** - * Body mixin - * - * Ref: https://fetch.spec.whatwg.org/#body - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -function Body(body) { - var _this = this; +module.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, - _ref$size = _ref.size; + return { + domain: result.string, + error: result.error + }; +}; - let size = _ref$size === undefined ? 0 : _ref$size; - var _ref$timeout = _ref.timeout; - let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; +module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - if (body == null) { - // body is undefined or null - body = null; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - body = Buffer.from(body.toString()); - } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - body = Buffer.from(body); - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); - } else if (body instanceof Stream) ; else { - // none of the above - // coerce to string then buffer - body = Buffer.from(String(body)); - } - this[INTERNALS] = { - body, - disturbed: false, - error: null - }; - this.size = size; - this.timeout = timeout; - if (body instanceof Stream) { - body.on('error', function (err) { - const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); - _this[INTERNALS].error = error; - }); - } -} +/***/ }), -Body.prototype = { - get body() { - return this[INTERNALS].body; - }, +/***/ 5871: +/***/ ((module) => { - get bodyUsed() { - return this[INTERNALS].disturbed; - }, +"use strict"; - /** - * Decode response as ArrayBuffer - * - * @return Promise - */ - arrayBuffer() { - return consumeBody.call(this).then(function (buf) { - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - }); - }, - /** - * Return raw response as Blob - * - * @return Promise - */ - blob() { - let ct = this.headers && this.headers.get('content-type') || ''; - return consumeBody.call(this).then(function (buf) { - return Object.assign( - // Prevent copying - new Blob([], { - type: ct.toLowerCase() - }), { - [BUFFER]: buf - }); - }); - }, +var conversions = {}; +module.exports = conversions; - /** - * Decode response as json - * - * @return Promise - */ - json() { - var _this2 = this; - - return consumeBody.call(this).then(function (buffer) { - try { - return JSON.parse(buffer.toString()); - } catch (err) { - return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); - } - }); - }, +function sign(x) { + return x < 0 ? -1 : 1; +} - /** - * Decode response as text - * - * @return Promise - */ - text() { - return consumeBody.call(this).then(function (buffer) { - return buffer.toString(); - }); - }, +function evenRound(x) { + // Round x to the nearest integer, choosing the even integer if it lies halfway between two. + if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) + return Math.floor(x); + } else { + return Math.round(x); + } +} - /** - * Decode response as buffer (non-spec api) - * - * @return Promise - */ - buffer() { - return consumeBody.call(this); - }, +function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength; + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); + const upperBound = Math.pow(2, bitLength) - 1; - /** - * Decode response as text, while automatically detecting the encoding and - * trying to decode to UTF-8 (non-spec api) - * - * @return Promise - */ - textConverted() { - var _this3 = this; + const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); + const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - return consumeBody.call(this).then(function (buffer) { - return convertBody(buffer, _this3.headers); - }); - } -}; + return function(V, opts) { + if (!opts) opts = {}; -// In browsers, all properties are enumerable. -Object.defineProperties(Body.prototype, { - body: { enumerable: true }, - bodyUsed: { enumerable: true }, - arrayBuffer: { enumerable: true }, - blob: { enumerable: true }, - json: { enumerable: true }, - text: { enumerable: true } -}); + let x = +V; -Body.mixIn = function (proto) { - for (const name of Object.getOwnPropertyNames(Body.prototype)) { - // istanbul ignore else: future proof - if (!(name in proto)) { - const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); - Object.defineProperty(proto, name, desc); - } - } -}; + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite number"); + } -/** - * Consume and convert an entire Body to a Buffer. - * - * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body - * - * @return Promise - */ -function consumeBody() { - var _this4 = this; + x = sign(x) * Math.floor(Math.abs(x)); + if (x < lowerBound || x > upperBound) { + throw new TypeError("Argument is not in byte range"); + } - if (this[INTERNALS].disturbed) { - return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); - } + return x; + } - this[INTERNALS].disturbed = true; + if (!isNaN(x) && opts.clamp) { + x = evenRound(x); - if (this[INTERNALS].error) { - return Body.Promise.reject(this[INTERNALS].error); - } + if (x < lowerBound) x = lowerBound; + if (x > upperBound) x = upperBound; + return x; + } - let body = this.body; + if (!Number.isFinite(x) || x === 0) { + return 0; + } - // body is null - if (body === null) { - return Body.Promise.resolve(Buffer.alloc(0)); - } + x = sign(x) * Math.floor(Math.abs(x)); + x = x % moduloVal; - // body is blob - if (isBlob(body)) { - body = body.stream(); - } + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal; + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal; + } else if (x === -0) { // don't return negative zero + return 0; + } + } - // body is buffer - if (Buffer.isBuffer(body)) { - return Body.Promise.resolve(body); - } + return x; + } +} - // istanbul ignore if: should never happen - if (!(body instanceof Stream)) { - return Body.Promise.resolve(Buffer.alloc(0)); - } +conversions["void"] = function () { + return undefined; +}; - // body is stream - // get ready to actually consume the body - let accum = []; - let accumBytes = 0; - let abort = false; +conversions["boolean"] = function (val) { + return !!val; +}; - return new Body.Promise(function (resolve, reject) { - let resTimeout; +conversions["byte"] = createNumberConversion(8, { unsigned: false }); +conversions["octet"] = createNumberConversion(8, { unsigned: true }); - // allow timeout on slow response body - if (_this4.timeout) { - resTimeout = setTimeout(function () { - abort = true; - reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); - }, _this4.timeout); - } +conversions["short"] = createNumberConversion(16, { unsigned: false }); +conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - // handle stream errors - body.on('error', function (err) { - if (err.name === 'AbortError') { - // if the request was aborted, reject with this Error - abort = true; - reject(err); - } else { - // other errors, such as incorrect content-encoding - reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); - } - }); +conversions["long"] = createNumberConversion(32, { unsigned: false }); +conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - body.on('data', function (chunk) { - if (abort || chunk === null) { - return; - } +conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); +conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - if (_this4.size && accumBytes + chunk.length > _this4.size) { - abort = true; - reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); - return; - } +conversions["double"] = function (V) { + const x = +V; - accumBytes += chunk.length; - accum.push(chunk); - }); + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite floating-point value"); + } - body.on('end', function () { - if (abort) { - return; - } + return x; +}; - clearTimeout(resTimeout); +conversions["unrestricted double"] = function (V) { + const x = +V; - try { - resolve(Buffer.concat(accum, accumBytes)); - } catch (err) { - // handle streams that have accumulated too much data (issue #414) - reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); - } - }); - }); -} + if (isNaN(x)) { + throw new TypeError("Argument is NaN"); + } -/** - * Detect buffer encoding and convert to target encoding - * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding - * - * @param Buffer buffer Incoming buffer - * @param String encoding Target encoding - * @return String - */ -function convertBody(buffer, headers) { - if (typeof convert !== 'function') { - throw new Error('The package `encoding` must be installed to use the textConverted() function'); - } + return x; +}; - const ct = headers.get('content-type'); - let charset = 'utf-8'; - let res, str; +// not quite valid, but good enough for JS +conversions["float"] = conversions["double"]; +conversions["unrestricted float"] = conversions["unrestricted double"]; - // header - if (ct) { - res = /charset=([^;]*)/i.exec(ct); - } +conversions["DOMString"] = function (V, opts) { + if (!opts) opts = {}; - // no charset in content type, peek at response body for at most 1024 bytes - str = buffer.slice(0, 1024).toString(); + if (opts.treatNullAsEmptyString && V === null) { + return ""; + } - // html5 - if (!res && str) { - res = / 255) { + throw new TypeError("Argument is not a valid bytestring"); + } + } - if (res) { - res = /charset=(.*)/i.exec(res.pop()); - } - } + return x; +}; - // xml - if (!res && str) { - res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); - } +conversions["USVString"] = function (V) { + const S = String(V); + const n = S.length; + const U = []; + for (let i = 0; i < n; ++i) { + const c = S.charCodeAt(i); + if (c < 0xD800 || c > 0xDFFF) { + U.push(String.fromCodePoint(c)); + } else if (0xDC00 <= c && c <= 0xDFFF) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + const d = S.charCodeAt(i + 1); + if (0xDC00 <= d && d <= 0xDFFF) { + const a = c & 0x3FF; + const b = d & 0x3FF; + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); + ++i; + } else { + U.push(String.fromCodePoint(0xFFFD)); + } + } + } + } - // found charset - if (res) { - charset = res.pop(); + return U.join(''); +}; - // prevent decode issues when sites use incorrect encoding - // ref: https://hsivonen.fi/encoding-menu/ - if (charset === 'gb2312' || charset === 'gbk') { - charset = 'gb18030'; - } - } +conversions["Date"] = function (V, opts) { + if (!(V instanceof Date)) { + throw new TypeError("Argument is not a Date object"); + } + if (isNaN(V)) { + return undefined; + } - // turn raw buffers into a single utf-8 buffer - return convert(buffer, 'UTF-8', charset).toString(); -} + return V; +}; -/** - * Detect a URLSearchParams object - * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 - * - * @param Object obj Object to detect by type or brand - * @return String - */ -function isURLSearchParams(obj) { - // Duck-typing as a necessary condition. - if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { - return false; - } +conversions["RegExp"] = function (V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V); + } - // Brand-checking and more duck-typing as optional condition. - return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; -} + return V; +}; -/** - * Check if `obj` is a W3C `Blob` object (which `File` inherits from) - * @param {*} obj - * @return {boolean} - */ -function isBlob(obj) { - return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); -} -/** - * Clone body given Res/Req instance - * - * @param Mixed instance Response or Request instance - * @return Mixed - */ -function clone(instance) { - let p1, p2; - let body = instance.body; +/***/ }), - // don't allow cloning a used body - if (instance.bodyUsed) { - throw new Error('cannot clone body after it is used'); - } +/***/ 8262: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // check that body is a stream and not form-data object - // note: we can't clone the form-data object without having it as a dependency - if (body instanceof Stream && typeof body.getBoundary !== 'function') { - // tee instance body - p1 = new PassThrough(); - p2 = new PassThrough(); - body.pipe(p1); - body.pipe(p2); - // set instance body to teed body and return the other teed body - instance[INTERNALS].body = p1; - body = p2; - } +"use strict"; - return body; -} +const usm = __nccwpck_require__(33); -/** - * Performs the operation "extract a `Content-Type` value from |object|" as - * specified in the specification: - * https://fetch.spec.whatwg.org/#concept-bodyinit-extract - * - * This function assumes that instance.body is present. - * - * @param Mixed instance Any options.body input - */ -function extractContentType(body) { - if (body === null) { - // body is null - return null; - } else if (typeof body === 'string') { - // body is string - return 'text/plain;charset=UTF-8'; - } else if (isURLSearchParams(body)) { - // body is a URLSearchParams - return 'application/x-www-form-urlencoded;charset=UTF-8'; - } else if (isBlob(body)) { - // body is blob - return body.type || null; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return null; - } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { - // body is ArrayBuffer - return null; - } else if (ArrayBuffer.isView(body)) { - // body is ArrayBufferView - return null; - } else if (typeof body.getBoundary === 'function') { - // detect form data input from form-data module - return `multipart/form-data;boundary=${body.getBoundary()}`; - } else if (body instanceof Stream) { - // body is stream - // can't really do much about this - return null; - } else { - // Body constructor defaults other things to string - return 'text/plain;charset=UTF-8'; - } -} +exports.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0]; + const base = constructorArgs[1]; -/** - * The Fetch Standard treats this as if "total bytes" is a property on the body. - * For us, we have to explicitly get it with a function. - * - * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes - * - * @param Body instance Instance of Body - * @return Number? Number of bytes, or null if not possible - */ -function getTotalBytes(instance) { - const body = instance.body; + let parsedBase = null; + if (base !== undefined) { + parsedBase = usm.basicURLParse(base); + if (parsedBase === "failure") { + throw new TypeError("Invalid base URL"); + } + } + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } - if (body === null) { - // body is null - return 0; - } else if (isBlob(body)) { - return body.size; - } else if (Buffer.isBuffer(body)) { - // body is buffer - return body.length; - } else if (body && typeof body.getLengthSync === 'function') { - // detect form data input from form-data module - if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x - body.hasKnownLength && body.hasKnownLength()) { - // 2.x - return body.getLengthSync(); - } - return null; - } else { - // body is stream - return null; - } -} + this._url = parsedURL; -/** - * Write a Body to a Node.js WritableStream (e.g. http.Request) object. - * - * @param Body instance Instance of Body - * @return Void - */ -function writeToStream(dest, instance) { - const body = instance.body; + // TODO: query stuff + } + get href() { + return usm.serializeURL(this._url); + } - if (body === null) { - // body is null - dest.end(); - } else if (isBlob(body)) { - body.stream().pipe(dest); - } else if (Buffer.isBuffer(body)) { - // body is buffer - dest.write(body); - dest.end(); - } else { - // body is stream - body.pipe(dest); - } -} + set href(v) { + const parsedURL = usm.basicURLParse(v); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } -// expose Promise -Body.Promise = global.Promise; + this._url = parsedURL; + } -/** - * headers.js - * - * Headers class offers convenient helpers - */ + get origin() { + return usm.serializeURLOrigin(this._url); + } -const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; -const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; + get protocol() { + return this._url.scheme + ":"; + } -function validateName(name) { - name = `${name}`; - if (invalidTokenRegex.test(name) || name === '') { - throw new TypeError(`${name} is not a legal HTTP header name`); - } -} + set protocol(v) { + usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); + } -function validateValue(value) { - value = `${value}`; - if (invalidHeaderCharRegex.test(value)) { - throw new TypeError(`${value} is not a legal HTTP header value`); - } -} + get username() { + return this._url.username; + } -/** - * Find the key in the map object given a header name. - * - * Returns undefined if not found. - * - * @param String name Header name - * @return String|Undefined - */ -function find(map, name) { - name = name.toLowerCase(); - for (const key in map) { - if (key.toLowerCase() === name) { - return key; - } - } - return undefined; -} + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } -const MAP = Symbol('map'); -class Headers { - /** - * Headers class - * - * @param Object headers Response headers - * @return Void - */ - constructor() { - let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + usm.setTheUsername(this._url, v); + } - this[MAP] = Object.create(null); + get password() { + return this._url.password; + } - if (init instanceof Headers) { - const rawHeaders = init.raw(); - const headerNames = Object.keys(rawHeaders); + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - for (const headerName of headerNames) { - for (const value of rawHeaders[headerName]) { - this.append(headerName, value); - } - } + usm.setThePassword(this._url, v); + } - return; - } + get host() { + const url = this._url; - // We don't worry about converting prop to ByteString here as append() - // will handle it. - if (init == null) ; else if (typeof init === 'object') { - const method = init[Symbol.iterator]; - if (method != null) { - if (typeof method !== 'function') { - throw new TypeError('Header pairs must be iterable'); - } + if (url.host === null) { + return ""; + } - // sequence> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { - throw new TypeError('Each header pair must be iterable'); - } - pairs.push(Array.from(pair)); - } + if (url.port === null) { + return usm.serializeHost(url.host); + } - for (const pair of pairs) { - if (pair.length !== 2) { - throw new TypeError('Each header pair must be a name/value tuple'); - } - this.append(pair[0], pair[1]); - } - } else { - // record - for (const key of Object.keys(init)) { - const value = init[key]; - this.append(key, value); - } - } - } else { - throw new TypeError('Provided initializer must be an object'); - } - } + return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); + } - /** - * Return combined header value given name - * - * @param String name Header name - * @return Mixed - */ - get(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key === undefined) { - return null; - } + set host(v) { + if (this._url.cannotBeABaseURL) { + return; + } - return this[MAP][key].join(', '); - } + usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); + } - /** - * Iterate over all headers - * - * @param Function callback Executed for each item with parameters (value, name, thisArg) - * @param Boolean thisArg `this` context for callback function - * @return Void - */ - forEach(callback) { - let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + get hostname() { + if (this._url.host === null) { + return ""; + } - let pairs = getHeaders(this); - let i = 0; - while (i < pairs.length) { - var _pairs$i = pairs[i]; - const name = _pairs$i[0], - value = _pairs$i[1]; + return usm.serializeHost(this._url.host); + } - callback.call(thisArg, value, name, this); - pairs = getHeaders(this); - i++; - } - } + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return; + } - /** - * Overwrite header values given name - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - set(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - this[MAP][key !== undefined ? key : name] = [value]; - } + usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); + } - /** - * Append a value onto existing header - * - * @param String name Header name - * @param String value Header value - * @return Void - */ - append(name, value) { - name = `${name}`; - value = `${value}`; - validateName(name); - validateValue(value); - const key = find(this[MAP], name); - if (key !== undefined) { - this[MAP][key].push(value); - } else { - this[MAP][name] = [value]; - } - } + get port() { + if (this._url.port === null) { + return ""; + } - /** - * Check for header name existence - * - * @param String name Header name - * @return Boolean - */ - has(name) { - name = `${name}`; - validateName(name); - return find(this[MAP], name) !== undefined; - } + return usm.serializeInteger(this._url.port); + } - /** - * Delete all header values given name - * - * @param String name Header name - * @return Void - */ - delete(name) { - name = `${name}`; - validateName(name); - const key = find(this[MAP], name); - if (key !== undefined) { - delete this[MAP][key]; - } - } - - /** - * Return raw headers (non-spec api) - * - * @return Object - */ - raw() { - return this[MAP]; - } - - /** - * Get an iterator on keys. - * - * @return Iterator - */ - keys() { - return createHeadersIterator(this, 'key'); - } + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } - /** - * Get an iterator on values. - * - * @return Iterator - */ - values() { - return createHeadersIterator(this, 'value'); - } + if (v === "") { + this._url.port = null; + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); + } + } - /** - * Get an iterator on entries. - * - * This is the default iterator of the Headers object. - * - * @return Iterator - */ - [Symbol.iterator]() { - return createHeadersIterator(this, 'key+value'); - } -} -Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0]; + } -Object.defineProperty(Headers.prototype, Symbol.toStringTag, { - value: 'Headers', - writable: false, - enumerable: false, - configurable: true -}); + if (this._url.path.length === 0) { + return ""; + } -Object.defineProperties(Headers.prototype, { - get: { enumerable: true }, - forEach: { enumerable: true }, - set: { enumerable: true }, - append: { enumerable: true }, - has: { enumerable: true }, - delete: { enumerable: true }, - keys: { enumerable: true }, - values: { enumerable: true }, - entries: { enumerable: true } -}); + return "/" + this._url.path.join("/"); + } -function getHeaders(headers) { - let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return; + } - const keys = Object.keys(headers[MAP]).sort(); - return keys.map(kind === 'key' ? function (k) { - return k.toLowerCase(); - } : kind === 'value' ? function (k) { - return headers[MAP][k].join(', '); - } : function (k) { - return [k.toLowerCase(), headers[MAP][k].join(', ')]; - }); -} + this._url.path = []; + usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); + } -const INTERNAL = Symbol('internal'); + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } -function createHeadersIterator(target, kind) { - const iterator = Object.create(HeadersIteratorPrototype); - iterator[INTERNAL] = { - target, - kind, - index: 0 - }; - return iterator; -} + return "?" + this._url.query; + } -const HeadersIteratorPrototype = Object.setPrototypeOf({ - next() { - // istanbul ignore if - if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { - throw new TypeError('Value of `this` is not a HeadersIterator'); - } + set search(v) { + // TODO: query stuff - var _INTERNAL = this[INTERNAL]; - const target = _INTERNAL.target, - kind = _INTERNAL.kind, - index = _INTERNAL.index; + const url = this._url; - const values = getHeaders(target, kind); - const len = values.length; - if (index >= len) { - return { - value: undefined, - done: true - }; - } + if (v === "") { + url.query = null; + return; + } - this[INTERNAL].index = index + 1; + const input = v[0] === "?" ? v.substring(1) : v; + url.query = ""; + usm.basicURLParse(input, { url, stateOverride: "query" }); + } - return { - value: values[index], - done: false - }; - } -}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } -Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { - value: 'HeadersIterator', - writable: false, - enumerable: false, - configurable: true -}); + return "#" + this._url.fragment; + } -/** - * Export the Headers object in a form that Node.js can consume. - * - * @param Headers headers - * @return Object - */ -function exportNodeCompatibleHeaders(headers) { - const obj = Object.assign({ __proto__: null }, headers[MAP]); + set hash(v) { + if (v === "") { + this._url.fragment = null; + return; + } - // http.request() only supports string as Host header. This hack makes - // specifying custom Host header possible. - const hostHeaderKey = find(headers[MAP], 'Host'); - if (hostHeaderKey !== undefined) { - obj[hostHeaderKey] = obj[hostHeaderKey][0]; - } + const input = v[0] === "#" ? v.substring(1) : v; + this._url.fragment = ""; + usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); + } - return obj; -} + toJSON() { + return this.href; + } +}; -/** - * Create a Headers object from an object of headers, ignoring those that do - * not conform to HTTP grammar productions. - * - * @param Object obj Object of headers - * @return Headers - */ -function createHeadersLenient(obj) { - const headers = new Headers(); - for (const name of Object.keys(obj)) { - if (invalidTokenRegex.test(name)) { - continue; - } - if (Array.isArray(obj[name])) { - for (const val of obj[name]) { - if (invalidHeaderCharRegex.test(val)) { - continue; - } - if (headers[MAP][name] === undefined) { - headers[MAP][name] = [val]; - } else { - headers[MAP][name].push(val); - } - } - } else if (!invalidHeaderCharRegex.test(obj[name])) { - headers[MAP][name] = [obj[name]]; - } - } - return headers; -} -const INTERNALS$1 = Symbol('Response internals'); +/***/ }), -// fix an issue where "STATUS_CODES" aren't a named export for node <10 -const STATUS_CODES = http.STATUS_CODES; +/***/ 653: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -/** - * Response class - * - * @param Stream body Readable stream - * @param Object opts Response options - * @return Void - */ -class Response { - constructor() { - let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; - let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +"use strict"; - Body.call(this, body, opts); - const status = opts.status || 200; - const headers = new Headers(opts.headers); +const conversions = __nccwpck_require__(5871); +const utils = __nccwpck_require__(276); +const Impl = __nccwpck_require__(8262); - if (body != null && !headers.has('Content-Type')) { - const contentType = extractContentType(body); - if (contentType) { - headers.append('Content-Type', contentType); - } - } +const impl = utils.implSymbol; - this[INTERNALS$1] = { - url: opts.url, - status, - statusText: opts.statusText || STATUS_CODES[status], - headers, - counter: opts.counter - }; - } - - get url() { - return this[INTERNALS$1].url || ''; - } +function URL(url) { + if (!this || this[impl] || !(this instanceof URL)) { + throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); + } + if (arguments.length < 1) { + throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); + } + const args = []; + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i]; + } + args[0] = conversions["USVString"](args[0]); + if (args[1] !== undefined) { + args[1] = conversions["USVString"](args[1]); + } - get status() { - return this[INTERNALS$1].status; - } + module.exports.setup(this, args); +} - /** - * Convenience property representing if the request ended normally - */ - get ok() { - return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; - } +URL.prototype.toJSON = function toJSON() { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + const args = []; + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i]; + } + return this[impl].toJSON.apply(this[impl], args); +}; +Object.defineProperty(URL.prototype, "href", { + get() { + return this[impl].href; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].href = V; + }, + enumerable: true, + configurable: true +}); - get redirected() { - return this[INTERNALS$1].counter > 0; - } +URL.prototype.toString = function () { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + return this.href; +}; - get statusText() { - return this[INTERNALS$1].statusText; - } +Object.defineProperty(URL.prototype, "origin", { + get() { + return this[impl].origin; + }, + enumerable: true, + configurable: true +}); - get headers() { - return this[INTERNALS$1].headers; - } +Object.defineProperty(URL.prototype, "protocol", { + get() { + return this[impl].protocol; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].protocol = V; + }, + enumerable: true, + configurable: true +}); - /** - * Clone this response - * - * @return Response - */ - clone() { - return new Response(clone(this), { - url: this.url, - status: this.status, - statusText: this.statusText, - headers: this.headers, - ok: this.ok, - redirected: this.redirected - }); - } -} +Object.defineProperty(URL.prototype, "username", { + get() { + return this[impl].username; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].username = V; + }, + enumerable: true, + configurable: true +}); -Body.mixIn(Response.prototype); +Object.defineProperty(URL.prototype, "password", { + get() { + return this[impl].password; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].password = V; + }, + enumerable: true, + configurable: true +}); -Object.defineProperties(Response.prototype, { - url: { enumerable: true }, - status: { enumerable: true }, - ok: { enumerable: true }, - redirected: { enumerable: true }, - statusText: { enumerable: true }, - headers: { enumerable: true }, - clone: { enumerable: true } +Object.defineProperty(URL.prototype, "host", { + get() { + return this[impl].host; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].host = V; + }, + enumerable: true, + configurable: true }); -Object.defineProperty(Response.prototype, Symbol.toStringTag, { - value: 'Response', - writable: false, - enumerable: false, - configurable: true +Object.defineProperty(URL.prototype, "hostname", { + get() { + return this[impl].hostname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hostname = V; + }, + enumerable: true, + configurable: true }); -const INTERNALS$2 = Symbol('Request internals'); -const URL = Url.URL || whatwgUrl.URL; +Object.defineProperty(URL.prototype, "port", { + get() { + return this[impl].port; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].port = V; + }, + enumerable: true, + configurable: true +}); -// fix an issue where "format", "parse" aren't a named export for node <10 -const parse_url = Url.parse; -const format_url = Url.format; +Object.defineProperty(URL.prototype, "pathname", { + get() { + return this[impl].pathname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].pathname = V; + }, + enumerable: true, + configurable: true +}); -/** - * Wrapper around `new URL` to handle arbitrary URLs - * - * @param {string} urlStr - * @return {void} - */ -function parseURL(urlStr) { - /* - Check whether the URL is absolute or not - Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 - Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 - */ - if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { - urlStr = new URL(urlStr).toString(); - } +Object.defineProperty(URL.prototype, "search", { + get() { + return this[impl].search; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].search = V; + }, + enumerable: true, + configurable: true +}); - // Fallback to old implementation for arbitrary URLs - return parse_url(urlStr); -} +Object.defineProperty(URL.prototype, "hash", { + get() { + return this[impl].hash; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hash = V; + }, + enumerable: true, + configurable: true +}); -const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; -/** - * Check if a value is an instance of Request. - * - * @param Mixed input - * @return Boolean - */ -function isRequest(input) { - return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; -} +module.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation; + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL.prototype); + this.setup(obj, constructorArgs, privateData); + return obj; + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {}; + privateData.wrapper = obj; -function isAbortSignal(signal) { - const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); - return !!(proto && proto.constructor.name === 'AbortSignal'); -} - -/** - * Request class - * - * @param Mixed input Url or Request instance - * @param Object init Custom options - * @return Void - */ -class Request { - constructor(input) { - let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - let parsedURL; - - // normalize input - if (!isRequest(input)) { - if (input && input.href) { - // in order to support Node.js' Url objects; though WHATWG's URL objects - // will fall into this branch also (since their `toString()` will return - // `href` property anyway) - parsedURL = parseURL(input.href); - } else { - // coerce input to a string before attempting to parse - parsedURL = parseURL(`${input}`); - } - input = {}; - } else { - parsedURL = parseURL(input.url); - } - - let method = init.method || input.method || 'GET'; - method = method.toUpperCase(); - - if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { - throw new TypeError('Request with GET/HEAD method cannot have body'); - } - - let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; - - Body.call(this, inputBody, { - timeout: init.timeout || input.timeout || 0, - size: init.size || input.size || 0 - }); - - const headers = new Headers(init.headers || input.headers || {}); - - if (inputBody != null && !headers.has('Content-Type')) { - const contentType = extractContentType(inputBody); - if (contentType) { - headers.append('Content-Type', contentType); - } - } - - let signal = isRequest(input) ? input.signal : null; - if ('signal' in init) signal = init.signal; - - if (signal != null && !isAbortSignal(signal)) { - throw new TypeError('Expected signal to be an instanceof AbortSignal'); - } - - this[INTERNALS$2] = { - method, - redirect: init.redirect || input.redirect || 'follow', - headers, - parsedURL, - signal - }; - - // node-fetch-only options - this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; - this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; - this.counter = init.counter || input.counter || 0; - this.agent = init.agent || input.agent; - } - - get method() { - return this[INTERNALS$2].method; - } - - get url() { - return format_url(this[INTERNALS$2].parsedURL); - } - - get headers() { - return this[INTERNALS$2].headers; - } - - get redirect() { - return this[INTERNALS$2].redirect; - } - - get signal() { - return this[INTERNALS$2].signal; - } - - /** - * Clone this request - * - * @return Request - */ - clone() { - return new Request(this); - } -} - -Body.mixIn(Request.prototype); - -Object.defineProperty(Request.prototype, Symbol.toStringTag, { - value: 'Request', - writable: false, - enumerable: false, - configurable: true -}); - -Object.defineProperties(Request.prototype, { - method: { enumerable: true }, - url: { enumerable: true }, - headers: { enumerable: true }, - redirect: { enumerable: true }, - clone: { enumerable: true }, - signal: { enumerable: true } -}); - -/** - * Convert a Request to Node.js http request options. - * - * @param Request A Request instance - * @return Object The options object to be passed to http.request - */ -function getNodeRequestOptions(request) { - const parsedURL = request[INTERNALS$2].parsedURL; - const headers = new Headers(request[INTERNALS$2].headers); - - // fetch step 1.3 - if (!headers.has('Accept')) { - headers.set('Accept', '*/*'); - } - - // Basic fetch - if (!parsedURL.protocol || !parsedURL.hostname) { - throw new TypeError('Only absolute URLs are supported'); - } - - if (!/^https?:$/.test(parsedURL.protocol)) { - throw new TypeError('Only HTTP(S) protocols are supported'); - } - - if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { - throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); - } - - // HTTP-network-or-cache fetch steps 2.4-2.7 - let contentLengthValue = null; - if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { - contentLengthValue = '0'; - } - if (request.body != null) { - const totalBytes = getTotalBytes(request); - if (typeof totalBytes === 'number') { - contentLengthValue = String(totalBytes); - } - } - if (contentLengthValue) { - headers.set('Content-Length', contentLengthValue); - } - - // HTTP-network-or-cache fetch step 2.11 - if (!headers.has('User-Agent')) { - headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); - } - - // HTTP-network-or-cache fetch step 2.15 - if (request.compress && !headers.has('Accept-Encoding')) { - headers.set('Accept-Encoding', 'gzip,deflate'); - } - - let agent = request.agent; - if (typeof agent === 'function') { - agent = agent(parsedURL); - } - - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close'); - } - - // HTTP-network fetch step 4.2 - // chunked encoding is handled by Node.js - - return Object.assign({}, parsedURL, { - method: request.method, - headers: exportNodeCompatibleHeaders(headers), - agent - }); -} + obj[impl] = new Impl.implementation(constructorArgs, privateData); + obj[impl][utils.wrapperSymbol] = obj; + }, + interface: URL, + expose: { + Window: { URL: URL }, + Worker: { URL: URL } + } +}; -/** - * abort-error.js - * - * AbortError interface for cancelled requests - */ -/** - * Create AbortError instance - * - * @param String message Error message for human - * @return AbortError - */ -function AbortError(message) { - Error.call(this, message); - this.type = 'aborted'; - this.message = message; +/***/ }), - // hide custom error implementation details from end-users - Error.captureStackTrace(this, this.constructor); -} +/***/ 3323: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -AbortError.prototype = Object.create(Error.prototype); -AbortError.prototype.constructor = AbortError; -AbortError.prototype.name = 'AbortError'; +"use strict"; -const URL$1 = Url.URL || whatwgUrl.URL; -// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 -const PassThrough$1 = Stream.PassThrough; +exports.URL = __nccwpck_require__(653)["interface"]; +exports.serializeURL = __nccwpck_require__(33).serializeURL; +exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; +exports.basicURLParse = __nccwpck_require__(33).basicURLParse; +exports.setTheUsername = __nccwpck_require__(33).setTheUsername; +exports.setThePassword = __nccwpck_require__(33).setThePassword; +exports.serializeHost = __nccwpck_require__(33).serializeHost; +exports.serializeInteger = __nccwpck_require__(33).serializeInteger; +exports.parseURL = __nccwpck_require__(33).parseURL; -const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { - const orig = new URL$1(original).hostname; - const dest = new URL$1(destination).hostname; - return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); -}; +/***/ }), -/** - * Fetch function - * - * @param Mixed url Absolute url or Request instance - * @param Object opts Fetch options - * @return Promise - */ -function fetch(url, opts) { - - // allow custom promise - if (!fetch.Promise) { - throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); - } - - Body.Promise = fetch.Promise; - - // wrap http.request into fetch - return new fetch.Promise(function (resolve, reject) { - // build request object - const request = new Request(url, opts); - const options = getNodeRequestOptions(request); - - const send = (options.protocol === 'https:' ? https : http).request; - const signal = request.signal; - - let response = null; - - const abort = function abort() { - let error = new AbortError('The user aborted a request.'); - reject(error); - if (request.body && request.body instanceof Stream.Readable) { - request.body.destroy(error); - } - if (!response || !response.body) return; - response.body.emit('error', error); - }; - - if (signal && signal.aborted) { - abort(); - return; - } - - const abortAndFinalize = function abortAndFinalize() { - abort(); - finalize(); - }; - - // send request - const req = send(options); - let reqTimeout; - - if (signal) { - signal.addEventListener('abort', abortAndFinalize); - } - - function finalize() { - req.abort(); - if (signal) signal.removeEventListener('abort', abortAndFinalize); - clearTimeout(reqTimeout); - } - - if (request.timeout) { - req.once('socket', function (socket) { - reqTimeout = setTimeout(function () { - reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); - finalize(); - }, request.timeout); - }); - } - - req.on('error', function (err) { - reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); - finalize(); - }); - - req.on('response', function (res) { - clearTimeout(reqTimeout); - - const headers = createHeadersLenient(res.headers); - - // HTTP fetch step 5 - if (fetch.isRedirect(res.statusCode)) { - // HTTP fetch step 5.2 - const location = headers.get('Location'); - - // HTTP fetch step 5.3 - let locationURL = null; - try { - locationURL = location === null ? null : new URL$1(location, request.url).toString(); - } catch (err) { - // error here can only be invalid URL in Location: header - // do not throw when options.redirect == manual - // let the user extract the errorneous redirect URL - if (request.redirect !== 'manual') { - reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); - finalize(); - return; - } - } - - // HTTP fetch step 5.5 - switch (request.redirect) { - case 'error': - reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); - finalize(); - return; - case 'manual': - // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. - if (locationURL !== null) { - // handle corrupted header - try { - headers.set('Location', locationURL); - } catch (err) { - // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request - reject(err); - } - } - break; - case 'follow': - // HTTP-redirect fetch step 2 - if (locationURL === null) { - break; - } - - // HTTP-redirect fetch step 5 - if (request.counter >= request.follow) { - reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 6 (counter increment) - // Create a new Request object. - const requestOpts = { - headers: new Headers(request.headers), - follow: request.follow, - counter: request.counter + 1, - agent: request.agent, - compress: request.compress, - method: request.method, - body: request.body, - signal: request.signal, - timeout: request.timeout, - size: request.size - }; - - if (!isDomainOrSubdomain(request.url, locationURL)) { - for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { - requestOpts.headers.delete(name); - } - } - - // HTTP-redirect fetch step 9 - if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { - reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); - finalize(); - return; - } - - // HTTP-redirect fetch step 11 - if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { - requestOpts.method = 'GET'; - requestOpts.body = undefined; - requestOpts.headers.delete('content-length'); - } - - // HTTP-redirect fetch step 15 - resolve(fetch(new Request(locationURL, requestOpts))); - finalize(); - return; - } - } - - // prepare response - res.once('end', function () { - if (signal) signal.removeEventListener('abort', abortAndFinalize); - }); - let body = res.pipe(new PassThrough$1()); - - const response_options = { - url: request.url, - status: res.statusCode, - statusText: res.statusMessage, - headers: headers, - size: request.size, - timeout: request.timeout, - counter: request.counter - }; - - // HTTP-network fetch step 12.1.1.3 - const codings = headers.get('Content-Encoding'); - - // HTTP-network fetch step 12.1.1.4: handle content codings - - // in following scenarios we ignore compression support - // 1. compression support is disabled - // 2. HEAD request - // 3. no Content-Encoding header - // 4. no content response (204) - // 5. content not modified response (304) - if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { - response = new Response(body, response_options); - resolve(response); - return; - } - - // For Node v6+ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - const zlibOptions = { - flush: zlib.Z_SYNC_FLUSH, - finishFlush: zlib.Z_SYNC_FLUSH - }; - - // for gzip - if (codings == 'gzip' || codings == 'x-gzip') { - body = body.pipe(zlib.createGunzip(zlibOptions)); - response = new Response(body, response_options); - resolve(response); - return; - } - - // for deflate - if (codings == 'deflate' || codings == 'x-deflate') { - // handle the infamous raw deflate response from old servers - // a hack for old IIS and Apache servers - const raw = res.pipe(new PassThrough$1()); - raw.once('data', function (chunk) { - // see http://stackoverflow.com/questions/37519828 - if ((chunk[0] & 0x0F) === 0x08) { - body = body.pipe(zlib.createInflate()); - } else { - body = body.pipe(zlib.createInflateRaw()); - } - response = new Response(body, response_options); - resolve(response); - }); - return; - } - - // for br - if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { - body = body.pipe(zlib.createBrotliDecompress()); - response = new Response(body, response_options); - resolve(response); - return; - } - - // otherwise, use response as-is - response = new Response(body, response_options); - resolve(response); - }); - - writeToStream(req, request); - }); -} -/** - * Redirect code matching - * - * @param Number code Status code - * @return Boolean - */ -fetch.isRedirect = function (code) { - return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; -}; - -// expose Promise -fetch.Promise = global.Promise; - -module.exports = exports = fetch; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports["default"] = exports; -exports.Headers = Headers; -exports.Request = Request; -exports.Response = Response; -exports.FetchError = FetchError; - - -/***/ }), - -/***/ 2299: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -var punycode = __nccwpck_require__(5477); -var mappingTable = __nccwpck_require__(1907); - -var PROCESSING_OPTIONS = { - TRANSITIONAL: 0, - NONTRANSITIONAL: 1 -}; - -function normalize(str) { // fix bug in v8 - return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); -} - -function findStatus(val) { - var start = 0; - var end = mappingTable.length - 1; - - while (start <= end) { - var mid = Math.floor((start + end) / 2); - - var target = mappingTable[mid]; - if (target[0][0] <= val && target[0][1] >= val) { - return target; - } else if (target[0][0] > val) { - end = mid - 1; - } else { - start = mid + 1; - } - } - - return null; -} - -var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; - -function countSymbols(string) { - return string - // replace every surrogate pair with a BMP symbol - .replace(regexAstralSymbols, '_') - // then get the length - .length; -} - -function mapChars(domain_name, useSTD3, processing_option) { - var hasError = false; - var processed = ""; - - var len = countSymbols(domain_name); - for (var i = 0; i < len; ++i) { - var codePoint = domain_name.codePointAt(i); - var status = findStatus(codePoint); - - switch (status[1]) { - case "disallowed": - hasError = true; - processed += String.fromCodePoint(codePoint); - break; - case "ignored": - break; - case "mapped": - processed += String.fromCodePoint.apply(String, status[2]); - break; - case "deviation": - if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { - processed += String.fromCodePoint.apply(String, status[2]); - } else { - processed += String.fromCodePoint(codePoint); - } - break; - case "valid": - processed += String.fromCodePoint(codePoint); - break; - case "disallowed_STD3_mapped": - if (useSTD3) { - hasError = true; - processed += String.fromCodePoint(codePoint); - } else { - processed += String.fromCodePoint.apply(String, status[2]); - } - break; - case "disallowed_STD3_valid": - if (useSTD3) { - hasError = true; - } - - processed += String.fromCodePoint(codePoint); - break; - } - } - - return { - string: processed, - error: hasError - }; -} - -var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; - -function validateLabel(label, processing_option) { - if (label.substr(0, 4) === "xn--") { - label = punycode.toUnicode(label); - processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; - } - - var error = false; - - if (normalize(label) !== label || - (label[3] === "-" && label[4] === "-") || - label[0] === "-" || label[label.length - 1] === "-" || - label.indexOf(".") !== -1 || - label.search(combiningMarksRegex) === 0) { - error = true; - } - - var len = countSymbols(label); - for (var i = 0; i < len; ++i) { - var status = findStatus(label.codePointAt(i)); - if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || - (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && - status[1] !== "valid" && status[1] !== "deviation")) { - error = true; - break; - } - } - - return { - label: label, - error: error - }; -} - -function processing(domain_name, useSTD3, processing_option) { - var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize(result.string); - - var labels = result.string.split("."); - for (var i = 0; i < labels.length; ++i) { - try { - var validation = validateLabel(labels[i]); - labels[i] = validation.label; - result.error = result.error || validation.error; - } catch(e) { - result.error = true; - } - } - - return { - string: labels.join("."), - error: result.error - }; -} - -module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { - var result = processing(domain_name, useSTD3, processing_option); - var labels = result.string.split("."); - labels = labels.map(function(l) { - try { - return punycode.toASCII(l); - } catch(e) { - result.error = true; - return l; - } - }); - - if (verifyDnsLength) { - var total = labels.slice(0, labels.length - 1).join(".").length; - if (total.length > 253 || total.length === 0) { - result.error = true; - } - - for (var i=0; i < labels.length; ++i) { - if (labels.length > 63 || labels.length === 0) { - result.error = true; - break; - } - } - } - - if (result.error) return null; - return labels.join("."); -}; - -module.exports.toUnicode = function(domain_name, useSTD3) { - var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); - - return { - domain: result.string, - error: result.error - }; -}; - -module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; - - -/***/ }), - -/***/ 5871: -/***/ ((module) => { - -"use strict"; - - -var conversions = {}; -module.exports = conversions; - -function sign(x) { - return x < 0 ? -1 : 1; -} - -function evenRound(x) { - // Round x to the nearest integer, choosing the even integer if it lies halfway between two. - if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) - return Math.floor(x); - } else { - return Math.round(x); - } -} - -function createNumberConversion(bitLength, typeOpts) { - if (!typeOpts.unsigned) { - --bitLength; - } - const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); - const upperBound = Math.pow(2, bitLength) - 1; - - const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); - const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); - - return function(V, opts) { - if (!opts) opts = {}; - - let x = +V; - - if (opts.enforceRange) { - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite number"); - } - - x = sign(x) * Math.floor(Math.abs(x)); - if (x < lowerBound || x > upperBound) { - throw new TypeError("Argument is not in byte range"); - } - - return x; - } - - if (!isNaN(x) && opts.clamp) { - x = evenRound(x); - - if (x < lowerBound) x = lowerBound; - if (x > upperBound) x = upperBound; - return x; - } - - if (!Number.isFinite(x) || x === 0) { - return 0; - } - - x = sign(x) * Math.floor(Math.abs(x)); - x = x % moduloVal; - - if (!typeOpts.unsigned && x >= moduloBound) { - return x - moduloVal; - } else if (typeOpts.unsigned) { - if (x < 0) { - x += moduloVal; - } else if (x === -0) { // don't return negative zero - return 0; - } - } - - return x; - } -} - -conversions["void"] = function () { - return undefined; -}; - -conversions["boolean"] = function (val) { - return !!val; -}; - -conversions["byte"] = createNumberConversion(8, { unsigned: false }); -conversions["octet"] = createNumberConversion(8, { unsigned: true }); - -conversions["short"] = createNumberConversion(16, { unsigned: false }); -conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); - -conversions["long"] = createNumberConversion(32, { unsigned: false }); -conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); - -conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); -conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); - -conversions["double"] = function (V) { - const x = +V; - - if (!Number.isFinite(x)) { - throw new TypeError("Argument is not a finite floating-point value"); - } - - return x; -}; - -conversions["unrestricted double"] = function (V) { - const x = +V; - - if (isNaN(x)) { - throw new TypeError("Argument is NaN"); - } - - return x; -}; - -// not quite valid, but good enough for JS -conversions["float"] = conversions["double"]; -conversions["unrestricted float"] = conversions["unrestricted double"]; - -conversions["DOMString"] = function (V, opts) { - if (!opts) opts = {}; - - if (opts.treatNullAsEmptyString && V === null) { - return ""; - } - - return String(V); -}; - -conversions["ByteString"] = function (V, opts) { - const x = String(V); - let c = undefined; - for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { - if (c > 255) { - throw new TypeError("Argument is not a valid bytestring"); - } - } - - return x; -}; - -conversions["USVString"] = function (V) { - const S = String(V); - const n = S.length; - const U = []; - for (let i = 0; i < n; ++i) { - const c = S.charCodeAt(i); - if (c < 0xD800 || c > 0xDFFF) { - U.push(String.fromCodePoint(c)); - } else if (0xDC00 <= c && c <= 0xDFFF) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - if (i === n - 1) { - U.push(String.fromCodePoint(0xFFFD)); - } else { - const d = S.charCodeAt(i + 1); - if (0xDC00 <= d && d <= 0xDFFF) { - const a = c & 0x3FF; - const b = d & 0x3FF; - U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); - ++i; - } else { - U.push(String.fromCodePoint(0xFFFD)); - } - } - } - } - - return U.join(''); -}; - -conversions["Date"] = function (V, opts) { - if (!(V instanceof Date)) { - throw new TypeError("Argument is not a Date object"); - } - if (isNaN(V)) { - return undefined; - } - - return V; -}; - -conversions["RegExp"] = function (V, opts) { - if (!(V instanceof RegExp)) { - V = new RegExp(V); - } - - return V; -}; - - -/***/ }), - -/***/ 8262: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -const usm = __nccwpck_require__(33); - -exports.implementation = class URLImpl { - constructor(constructorArgs) { - const url = constructorArgs[0]; - const base = constructorArgs[1]; - - let parsedBase = null; - if (base !== undefined) { - parsedBase = usm.basicURLParse(base); - if (parsedBase === "failure") { - throw new TypeError("Invalid base URL"); - } - } - - const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - - // TODO: query stuff - } - - get href() { - return usm.serializeURL(this._url); - } - - set href(v) { - const parsedURL = usm.basicURLParse(v); - if (parsedURL === "failure") { - throw new TypeError("Invalid URL"); - } - - this._url = parsedURL; - } - - get origin() { - return usm.serializeURLOrigin(this._url); - } - - get protocol() { - return this._url.scheme + ":"; - } - - set protocol(v) { - usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); - } - - get username() { - return this._url.username; - } - - set username(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setTheUsername(this._url, v); - } - - get password() { - return this._url.password; - } - - set password(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - usm.setThePassword(this._url, v); - } - - get host() { - const url = this._url; - - if (url.host === null) { - return ""; - } - - if (url.port === null) { - return usm.serializeHost(url.host); - } - - return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); - } - - set host(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); - } - - get hostname() { - if (this._url.host === null) { - return ""; - } - - return usm.serializeHost(this._url.host); - } - - set hostname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); - } - - get port() { - if (this._url.port === null) { - return ""; - } - - return usm.serializeInteger(this._url.port); - } - - set port(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return; - } - - if (v === "") { - this._url.port = null; - } else { - usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); - } - } - - get pathname() { - if (this._url.cannotBeABaseURL) { - return this._url.path[0]; - } - - if (this._url.path.length === 0) { - return ""; - } - - return "/" + this._url.path.join("/"); - } - - set pathname(v) { - if (this._url.cannotBeABaseURL) { - return; - } - - this._url.path = []; - usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); - } - - get search() { - if (this._url.query === null || this._url.query === "") { - return ""; - } - - return "?" + this._url.query; - } - - set search(v) { - // TODO: query stuff - - const url = this._url; - - if (v === "") { - url.query = null; - return; - } - - const input = v[0] === "?" ? v.substring(1) : v; - url.query = ""; - usm.basicURLParse(input, { url, stateOverride: "query" }); - } - - get hash() { - if (this._url.fragment === null || this._url.fragment === "") { - return ""; - } - - return "#" + this._url.fragment; - } - - set hash(v) { - if (v === "") { - this._url.fragment = null; - return; - } - - const input = v[0] === "#" ? v.substring(1) : v; - this._url.fragment = ""; - usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); - } - - toJSON() { - return this.href; - } -}; - - -/***/ }), - -/***/ 653: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const conversions = __nccwpck_require__(5871); -const utils = __nccwpck_require__(276); -const Impl = __nccwpck_require__(8262); - -const impl = utils.implSymbol; - -function URL(url) { - if (!this || this[impl] || !(this instanceof URL)) { - throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); - } - if (arguments.length < 1) { - throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); - } - const args = []; - for (let i = 0; i < arguments.length && i < 2; ++i) { - args[i] = arguments[i]; - } - args[0] = conversions["USVString"](args[0]); - if (args[1] !== undefined) { - args[1] = conversions["USVString"](args[1]); - } - - module.exports.setup(this, args); -} - -URL.prototype.toJSON = function toJSON() { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - const args = []; - for (let i = 0; i < arguments.length && i < 0; ++i) { - args[i] = arguments[i]; - } - return this[impl].toJSON.apply(this[impl], args); -}; -Object.defineProperty(URL.prototype, "href", { - get() { - return this[impl].href; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].href = V; - }, - enumerable: true, - configurable: true -}); - -URL.prototype.toString = function () { - if (!this || !module.exports.is(this)) { - throw new TypeError("Illegal invocation"); - } - return this.href; -}; - -Object.defineProperty(URL.prototype, "origin", { - get() { - return this[impl].origin; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "protocol", { - get() { - return this[impl].protocol; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].protocol = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "username", { - get() { - return this[impl].username; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].username = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "password", { - get() { - return this[impl].password; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].password = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "host", { - get() { - return this[impl].host; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].host = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hostname", { - get() { - return this[impl].hostname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hostname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "port", { - get() { - return this[impl].port; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].port = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "pathname", { - get() { - return this[impl].pathname; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].pathname = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "search", { - get() { - return this[impl].search; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].search = V; - }, - enumerable: true, - configurable: true -}); - -Object.defineProperty(URL.prototype, "hash", { - get() { - return this[impl].hash; - }, - set(V) { - V = conversions["USVString"](V); - this[impl].hash = V; - }, - enumerable: true, - configurable: true -}); - - -module.exports = { - is(obj) { - return !!obj && obj[impl] instanceof Impl.implementation; - }, - create(constructorArgs, privateData) { - let obj = Object.create(URL.prototype); - this.setup(obj, constructorArgs, privateData); - return obj; - }, - setup(obj, constructorArgs, privateData) { - if (!privateData) privateData = {}; - privateData.wrapper = obj; - - obj[impl] = new Impl.implementation(constructorArgs, privateData); - obj[impl][utils.wrapperSymbol] = obj; - }, - interface: URL, - expose: { - Window: { URL: URL }, - Worker: { URL: URL } - } -}; - - - -/***/ }), - -/***/ 3323: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -exports.URL = __nccwpck_require__(653)["interface"]; -exports.serializeURL = __nccwpck_require__(33).serializeURL; -exports.serializeURLOrigin = __nccwpck_require__(33).serializeURLOrigin; -exports.basicURLParse = __nccwpck_require__(33).basicURLParse; -exports.setTheUsername = __nccwpck_require__(33).setTheUsername; -exports.setThePassword = __nccwpck_require__(33).setThePassword; -exports.serializeHost = __nccwpck_require__(33).serializeHost; -exports.serializeInteger = __nccwpck_require__(33).serializeInteger; -exports.parseURL = __nccwpck_require__(33).parseURL; - - -/***/ }), - -/***/ 33: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 33: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; @@ -13840,2314 +11535,769 @@ function wrappy (fn, cb) { /***/ }), -/***/ 2877: -/***/ ((module) => { - -module.exports = eval("require")("encoding"); - - -/***/ }), - -/***/ 9491: -/***/ ((module) => { - -"use strict"; -module.exports = require("assert"); - -/***/ }), - -/***/ 6113: -/***/ ((module) => { - -"use strict"; -module.exports = require("crypto"); - -/***/ }), - -/***/ 2361: -/***/ ((module) => { - -"use strict"; -module.exports = require("events"); - -/***/ }), - -/***/ 7147: -/***/ ((module) => { - -"use strict"; -module.exports = require("fs"); - -/***/ }), - -/***/ 3685: -/***/ ((module) => { - -"use strict"; -module.exports = require("http"); - -/***/ }), - -/***/ 5687: -/***/ ((module) => { - -"use strict"; -module.exports = require("https"); - -/***/ }), - -/***/ 1808: -/***/ ((module) => { - -"use strict"; -module.exports = require("net"); - -/***/ }), - -/***/ 2037: -/***/ ((module) => { - -"use strict"; -module.exports = require("os"); - -/***/ }), - -/***/ 1017: -/***/ ((module) => { - -"use strict"; -module.exports = require("path"); - -/***/ }), - -/***/ 5477: -/***/ ((module) => { - -"use strict"; -module.exports = require("punycode"); - -/***/ }), - -/***/ 2781: -/***/ ((module) => { - -"use strict"; -module.exports = require("stream"); - -/***/ }), - -/***/ 4404: -/***/ ((module) => { - -"use strict"; -module.exports = require("tls"); - -/***/ }), - -/***/ 7310: -/***/ ((module) => { - -"use strict"; -module.exports = require("url"); - -/***/ }), - -/***/ 3837: -/***/ ((module) => { - -"use strict"; -module.exports = require("util"); - -/***/ }), - -/***/ 9796: -/***/ ((module) => { +/***/ 2483: +/***/ (function(module, exports, __nccwpck_require__) { "use strict"; -module.exports = require("zlib"); - -/***/ }), - -/***/ 6717: -/***/ ((__unused_webpack_module, exports) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); - -// Current version. -var VERSION = '1.13.6'; - -// Establish the root object, `window` (`self`) in the browser, `global` -// on the server, or `this` in some virtual machines. We use `self` -// instead of `window` for `WebWorker` support. -var root = (typeof self == 'object' && self.self === self && self) || - (typeof global == 'object' && global.global === global && global) || - Function('return this')() || - {}; - -// Save bytes in the minified (but not gzipped) version: -var ArrayProto = Array.prototype, ObjProto = Object.prototype; -var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - -// Create quick reference variables for speed access to core prototypes. -var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - -// Modern feature detection. -var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', - supportsDataView = typeof DataView !== 'undefined'; - -// All **ECMAScript 5+** native function implementations that we hope to use -// are declared here. -var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create, - nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; - -// Create references to these builtin functions because we override them. -var _isNaN = isNaN, - _isFinite = isFinite; - -// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. -var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); -var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - -// The largest integer that can be represented exactly. -var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - -// Some functions take a variable number of arguments, or a few expected -// arguments at the beginning and then a variable number of values to operate -// on. This helper accumulates all remaining arguments past the function’s -// argument length (or an explicit `startIndex`), into an array that becomes -// the last argument. Similar to ES6’s "rest parameter". -function restArguments(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; -} - -// Is a given variable an object? -function isObject(obj) { - var type = typeof obj; - return type === 'function' || (type === 'object' && !!obj); -} - -// Is a given value equal to null? -function isNull(obj) { - return obj === null; -} - -// Is a given variable undefined? -function isUndefined(obj) { - return obj === void 0; -} - -// Is a given value a boolean? -function isBoolean(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; -} - -// Is a given value a DOM element? -function isElement(obj) { - return !!(obj && obj.nodeType === 1); -} - -// Internal function for creating a `toString`-based type tester. -function tagTester(name) { - var tag = '[object ' + name + ']'; - return function(obj) { - return toString.call(obj) === tag; - }; -} - -var isString = tagTester('String'); - -var isNumber = tagTester('Number'); - -var isDate = tagTester('Date'); - -var isRegExp = tagTester('RegExp'); - -var isError = tagTester('Error'); - -var isSymbol = tagTester('Symbol'); - -var isArrayBuffer = tagTester('ArrayBuffer'); - -var isFunction = tagTester('Function'); - -// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old -// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). -var nodelist = root.document && root.document.childNodes; -if ( true && typeof Int8Array != 'object' && typeof nodelist != 'function') { - isFunction = function(obj) { - return typeof obj == 'function' || false; - }; -} - -var isFunction$1 = isFunction; - -var hasObjectTag = tagTester('Object'); - -// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. -// In IE 11, the most common among them, this problem also applies to -// `Map`, `WeakMap` and `Set`. -var hasStringTagBug = ( - supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) - ), - isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); - -var isDataView = tagTester('DataView'); - -// In IE 10 - Edge 13, we need a different heuristic -// to determine whether an object is a `DataView`. -function ie10IsDataView(obj) { - return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); -} - -var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); - -// Is a given value an array? -// Delegates to ECMA5's native `Array.isArray`. -var isArray = nativeIsArray || tagTester('Array'); - -// Internal function to check whether `key` is an own property name of `obj`. -function has$1(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); -} - -var isArguments = tagTester('Arguments'); - -// Define a fallback version of the method in browsers (ahem, IE < 9), where -// there isn't any inspectable "Arguments" type. -(function() { - if (!isArguments(arguments)) { - isArguments = function(obj) { - return has$1(obj, 'callee'); - }; - } -}()); - -var isArguments$1 = isArguments; - -// Is a given object a finite number? -function isFinite$1(obj) { - return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); -} - -// Is the given value `NaN`? -function isNaN$1(obj) { - return isNumber(obj) && _isNaN(obj); +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core_1 = __importDefault(__nccwpck_require__(2186)); +const github_1 = __nccwpck_require__(5438); +const ActionUtils = __importStar(__nccwpck_require__(970)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GithubUtils_1 = __importDefault(__nccwpck_require__(9296)); +/** + * Return a nicely formatted message for the table based on the result of the GitHub action job + */ +function getDeployTableMessage(platformResult) { + switch (platformResult) { + case 'success': + return `${platformResult} ✅`; + case 'cancelled': + return `${platformResult} 🔪`; + case 'skipped': + return `${platformResult} 🚫`; + case 'failure': + default: + return `${platformResult} ❌`; + } } - -// Predicate-generating function. Often useful outside of Underscore. -function constant(value) { - return function() { - return value; - }; +/** + * Comment Single PR + */ +async function commentPR(PR, message) { + try { + await GithubUtils_1.default.createComment(github_1.context.repo.repo, PR, message); + console.log(`Comment created on #${PR} successfully 🎉`); + } + catch (err) { + console.log(`Unable to write comment on #${PR} 😞`); + if (err instanceof Error) { + core_1.default.setFailed(err.message); + } + } } - -// Common internal logic for `isArrayLike` and `isBufferLike`. -function createSizePropertyCheck(getSizeProperty) { - return function(collection) { - var sizeProperty = getSizeProperty(collection); - return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; - } +const workflowURL = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; +async function run() { + const prList = ActionUtils.getJSONInput('PR_LIST', { required: true }).map((num) => Number.parseInt(num, 10)); + const isProd = ActionUtils.getJSONInput('IS_PRODUCTION_DEPLOY', { required: true }); + const version = core_1.default.getInput('DEPLOY_VERSION', { required: true }); + const androidResult = getDeployTableMessage(core_1.default.getInput('ANDROID', { required: true })); + const desktopResult = getDeployTableMessage(core_1.default.getInput('DESKTOP', { required: true })); + const iOSResult = getDeployTableMessage(core_1.default.getInput('IOS', { required: true })); + const webResult = getDeployTableMessage(core_1.default.getInput('WEB', { required: true })); + function getDeployMessage(deployer, deployVerb, prTitle) { + let message = `🚀 [${deployVerb}](${workflowURL}) to ${isProd ? 'production' : 'staging'}`; + message += ` by https://github.com/${deployer} in version: ${version} 🚀`; + message += `\n\nplatform | result\n---|---\n🤖 android 🤖|${androidResult}\n🖥 desktop 🖥|${desktopResult}`; + message += `\n🍎 iOS 🍎|${iOSResult}\n🕸 web 🕸|${webResult}`; + if (deployVerb === 'Cherry-picked' && !/no ?qa/gi.test(prTitle ?? '')) { + // eslint-disable-next-line max-len + message += + '\n\n@Expensify/applauseleads please QA this PR and check it off on the [deploy checklist](https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3AStagingDeployCash) if it passes.'; + } + return message; + } + if (isProd) { + // Find the previous deploy checklist + const { data: deployChecklists } = await GithubUtils_1.default.octokit.issues.listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'closed', + }); + const previousChecklistID = deployChecklists[0].number; + // who closed the last deploy checklist? + const deployer = await GithubUtils_1.default.getActorWhoClosedIssue(previousChecklistID); + // Create comment on each pull request (one at a time to avoid throttling issues) + const deployMessage = getDeployMessage(deployer, 'Deployed'); + for (const pr of prList) { + await commentPR(pr, deployMessage); + } + return; + } + // First find out if this is a normal staging deploy or a CP by looking at the commit message on the tag + const { data: recentTags } = await GithubUtils_1.default.octokit.repos.listTags({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }); + const currentTag = recentTags.find((tag) => tag.name === version); + if (!currentTag) { + const err = `Could not find tag matching ${version}`; + console.error(err); + core_1.default.setFailed(err); + return; + } + const { data: commit } = await GithubUtils_1.default.octokit.git.getCommit({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + commit_sha: currentTag.commit.sha, + }); + const isCP = /[\S\s]*\(cherry picked from commit .*\)/.test(commit.message); + for (const prNumber of prList) { + /* + * Determine who the deployer for the PR is. The "deployer" for staging deploys is: + * 1. For regular staging deploys, the person who merged the PR. + * 2. For CPs, the person who committed the cherry-picked commit (not necessarily the author of the commit). + */ + const { data: pr } = await GithubUtils_1.default.octokit.pulls.get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: prNumber, + }); + const deployer = isCP ? commit.committer.name : pr.merged_by?.login; + const title = pr.title; + const deployMessage = deployer ? getDeployMessage(deployer, isCP ? 'Cherry-picked' : 'Deployed', title) : ''; + await commentPR(prNumber, deployMessage); + } } - -// Internal helper to generate a function to obtain property `key` from `obj`. -function shallowProperty(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; +if (require.main === require.cache[eval('__filename')]) { + run(); } +module.exports = run; -// Internal helper to obtain the `byteLength` property of an object. -var getByteLength = shallowProperty('byteLength'); - -// Internal helper to determine whether we should spend extensive checks against -// `ArrayBuffer` et al. -var isBufferLike = createSizePropertyCheck(getByteLength); -// Is a given value a typed array? -var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; -function isTypedArray(obj) { - // `ArrayBuffer.isView` is the most future-proof, so use it when available. - // Otherwise, fall back on the above regular expression. - return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : - isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); -} +/***/ }), -var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { -// Internal helper to obtain the `length` property of an object. -var getLength = shallowProperty('length'); +"use strict"; -// Internal helper to create a simple lookup structure. -// `collectNonEnumProps` used to depend on `_.contains`, but this led to -// circular imports. `emulatedSet` is a one-off solution that only works for -// arrays of strings. -function emulatedSet(keys) { - var hash = {}; - for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; - return { - contains: function(key) { return hash[key] === true; }, - push: function(key) { - hash[key] = true; - return keys.push(key); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; } - }; -} - -// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't -// be iterated by `for key in ...` and thus missed. Extends `keys` in place if -// needed. -function collectNonEnumProps(obj, keys) { - keys = emulatedSet(keys); - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto; - - // Constructor is a special case. - var prop = 'constructor'; - if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); - - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { - keys.push(prop); + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); } - } -} - -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native `Object.keys`. -function keys(obj) { - if (!isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has$1(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -function isEmpty(obj) { - if (obj == null) return true; - // Skip the more expensive `toString`-based type checks if `obj` has no - // `.length`. - var length = getLength(obj); - if (typeof length == 'number' && ( - isArray(obj) || isString(obj) || isArguments$1(obj) - )) return length === 0; - return getLength(keys(obj)) === 0; -} - -// Returns whether an object has a given set of `key:value` pairs. -function isMatch(object, attrs) { - var _keys = keys(attrs), length = _keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = _keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; -} - -// If Underscore is called as a function, it returns a wrapped object that can -// be used OO-style. This wrapper holds altered versions of all functions added -// through `_.mixin`. Wrapped objects may be chained. -function _$1(obj) { - if (obj instanceof _$1) return obj; - if (!(this instanceof _$1)) return new _$1(obj); - this._wrapped = obj; -} - -_$1.VERSION = VERSION; - -// Extracts the result from a wrapped and chained object. -_$1.prototype.value = function() { - return this._wrapped; -}; - -// Provide unwrapping proxies for some methods used in engine operations -// such as arithmetic and JSON stringification. -_$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; - -_$1.prototype.toString = function() { - return String(this._wrapped); -}; - -// Internal function to wrap or shallow-copy an ArrayBuffer, -// typed array or DataView to a new view, reusing the buffer. -function toBufferView(bufferSource) { - return new Uint8Array( - bufferSource.buffer || bufferSource, - bufferSource.byteOffset || 0, - getByteLength(bufferSource) - ); -} - -// We use this string twice, so give it a name for minification. -var tagDataView = '[object DataView]'; - -// Internal recursive comparison function for `_.isEqual`. -function eq(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -// Internal recursive comparison function for `_.isEqual`. -function deepEq(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _$1) a = a._wrapped; - if (b instanceof _$1) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - // Work around a bug in IE 10 - Edge 13. - if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { - if (!isDataView$1(b)) return false; - className = tagDataView; - } - switch (className) { - // These types are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - case '[object ArrayBuffer]': - case tagDataView: - // Coerce to typed array so we can fall through. - return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); - } - - var areArrays = className === '[object Array]'; - if (!areArrays && isTypedArray$1(a)) { - var byteLength = getByteLength(a); - if (byteLength !== getByteLength(b)) return false; - if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; - areArrays = true; - } - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && - isFunction$1(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); } - } else { - // Deep compare objects. - var _keys = keys(a), key; - length = _keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = _keys[length]; - if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -// Perform a deep comparison to check if two objects are equal. -function isEqual(a, b) { - return eq(a, b); -} - -// Retrieve all the enumerable property names of an object. -function allKeys(obj) { - if (!isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Since the regular `Object.prototype.toString` type tests don't work for -// some types in IE 11, we use a fingerprinting heuristic instead, based -// on the methods. It's not great, but it's the best we got. -// The fingerprint method lists are defined below. -function ie11fingerprint(methods) { - var length = getLength(methods); - return function(obj) { - if (obj == null) return false; - // `Map`, `WeakMap` and `Set` have no enumerable keys. - var keys = allKeys(obj); - if (getLength(keys)) return false; - for (var i = 0; i < length; i++) { - if (!isFunction$1(obj[methods[i]])) return false; - } - // If we are testing against `WeakMap`, we need to ensure that - // `obj` doesn't have a `forEach` method in order to distinguish - // it from a regular `Map`. - return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); - }; -} - -// In the interest of compact minification, we write -// each string in the fingerprints only once. -var forEachName = 'forEach', - hasName = 'has', - commonInit = ['clear', 'delete'], - mapTail = ['get', hasName, 'set']; - -// `Map`, `WeakMap` and `Set` each have slightly different -// combinations of the above sublists. -var mapMethods = commonInit.concat(forEachName, mapTail), - weakMapMethods = commonInit.concat(mapTail), - setMethods = ['add'].concat(commonInit, forEachName, hasName); - -var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); - -var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); - -var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); - -var isWeakSet = tagTester('WeakSet'); - -// Retrieve the values of an object's properties. -function values(obj) { - var _keys = keys(obj); - var length = _keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[_keys[i]]; - } - return values; -} - -// Convert an object into a list of `[key, value]` pairs. -// The opposite of `_.object` with one argument. -function pairs(obj) { - var _keys = keys(obj); - var length = _keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [_keys[i], obj[_keys[i]]]; - } - return pairs; -} - -// Invert the keys and values of an object. The values must be serializable. -function invert(obj) { - var result = {}; - var _keys = keys(obj); - for (var i = 0, length = _keys.length; i < length; i++) { - result[obj[_keys[i]]] = _keys[i]; - } - return result; -} - -// Return a sorted list of the function names available on the object. -function functions(obj) { - var names = []; - for (var key in obj) { - if (isFunction$1(obj[key])) names.push(key); - } - return names.sort(); -} - -// An internal function for creating assigner functions. -function createAssigner(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); } - return obj; - }; -} - -// Extend a given object with all the properties in passed-in object(s). -var extend = createAssigner(allKeys); - -// Assigns a given object with all the own properties in the passed-in -// object(s). -// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) -var extendOwn = createAssigner(keys); - -// Fill in a given object with default properties. -var defaults = createAssigner(allKeys, true); - -// Create a naked function reference for surrogate-prototype-swapping. -function ctor() { - return function(){}; -} - -// An internal function for creating a new object that inherits from another. -function baseCreate(prototype) { - if (!isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - var Ctor = ctor(); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; -} - -// Creates an object that inherits from the given prototype object. -// If additional properties are provided then they will be added to the -// created object. -function create(prototype, props) { - var result = baseCreate(prototype); - if (props) extendOwn(result, props); - return result; -} - -// Create a (shallow-cloned) duplicate of an object. -function clone(obj) { - if (!isObject(obj)) return obj; - return isArray(obj) ? obj.slice() : extend({}, obj); -} - -// Invokes `interceptor` with the `obj` and then returns `obj`. -// The primary purpose of this method is to "tap into" a method chain, in -// order to perform operations on intermediate results within the chain. -function tap(obj, interceptor) { - interceptor(obj); - return obj; -} - -// Normalize a (deep) property `path` to array. -// Like `_.iteratee`, this function can be customized. -function toPath$1(path) { - return isArray(path) ? path : [path]; -} -_$1.toPath = toPath$1; - -// Internal wrapper for `_.toPath` to enable minification. -// Similar to `cb` for `_.iteratee`. -function toPath(path) { - return _$1.toPath(path); -} - -// Internal function to obtain a nested property in `obj` along `path`. -function deepGet(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; -} - -// Get the value of the (deep) property on `path` from `object`. -// If any property in `path` does not exist or if the value is -// `undefined`, return `defaultValue` instead. -// The `path` is normalized through `_.toPath`. -function get(object, path, defaultValue) { - var value = deepGet(object, toPath(path)); - return isUndefined(value) ? defaultValue : value; -} - -// Shortcut function for checking if an object has a given property directly on -// itself (in other words, not on a prototype). Unlike the internal `has` -// function, this public version can also traverse nested properties. -function has(obj, path) { - path = toPath(path); - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (!has$1(obj, key)) return false; - obj = obj[key]; - } - return !!length; -} - -// Keep the identity function around for default iteratees. -function identity(value) { - return value; -} - -// Returns a predicate for checking whether an object has a given set of -// `key:value` pairs. -function matcher(attrs) { - attrs = extendOwn({}, attrs); - return function(obj) { - return isMatch(obj, attrs); - }; -} - -// Creates a function that, when passed an object, will traverse that object’s -// properties down the given `path`, specified as an array of keys or indices. -function property(path) { - path = toPath(path); - return function(obj) { - return deepGet(obj, path); - }; -} - -// Internal function that returns an efficient (for current engines) version -// of the passed-in callback, to be repeatedly applied in other Underscore -// functions. -function optimizeCb(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; -} - -// An internal function to generate callbacks that can be applied to each -// element in a collection, returning the desired result — either `_.identity`, -// an arbitrary callback, a property matcher, or a property accessor. -function baseIteratee(value, context, argCount) { - if (value == null) return identity; - if (isFunction$1(value)) return optimizeCb(value, context, argCount); - if (isObject(value) && !isArray(value)) return matcher(value); - return property(value); -} - -// External wrapper for our callback generator. Users may customize -// `_.iteratee` if they want additional predicate/iteratee shorthand styles. -// This abstraction hides the internal-only `argCount` argument. -function iteratee(value, context) { - return baseIteratee(value, context, Infinity); -} -_$1.iteratee = iteratee; - -// The function we call internally to generate a callback. It invokes -// `_.iteratee` if overridden, otherwise `baseIteratee`. -function cb(value, context, argCount) { - if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); - return baseIteratee(value, context, argCount); -} - -// Returns the results of applying the `iteratee` to each element of `obj`. -// In contrast to `_.map` it returns an object. -function mapObject(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = keys(obj), - length = _keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = _keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Predicate-generating function. Often useful outside of Underscore. -function noop(){} - -// Generates a function for a given object that returns a given property. -function propertyOf(obj) { - if (obj == null) return noop; - return function(path) { - return get(obj, path); - }; -} - -// Run a function **n** times. -function times(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; -} - -// Return a random integer between `min` and `max` (inclusive). -function random(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); -} - -// A (possibly faster) way to get the current timestamp as an integer. -var now = Date.now || function() { - return new Date().getTime(); -}; - -// Internal helper to generate functions for escaping and unescaping strings -// to/from HTML interpolation. -function createEscaper(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; -} - -// Internal list of HTML entities for escaping. -var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' -}; - -// Function for escaping strings to HTML interpolation. -var _escape = createEscaper(escapeMap); - -// Internal list of HTML entities for unescaping. -var unescapeMap = invert(escapeMap); - -// Function for unescaping strings from HTML interpolation. -var _unescape = createEscaper(unescapeMap); - -// By default, Underscore uses ERB-style template delimiters. Change the -// following template settings to use alternative delimiters. -var templateSettings = _$1.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g -}; - -// When customizing `_.templateSettings`, if you don't want to define an -// interpolation, evaluation or escaping regex, we need one that is -// guaranteed not to match. -var noMatch = /(.)^/; - -// Certain characters need to be escaped so that they can be put into a -// string literal. -var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' -}; - -var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - -function escapeChar(match) { - return '\\' + escapes[match]; -} - -// In order to prevent third-party code injection through -// `_.templateSettings.variable`, we test it against the following regular -// expression. It is intentionally a bit more liberal than just matching valid -// identifiers, but still prevents possible loopholes through defaults or -// destructuring assignment. -var bareIdentifier = /^\s*(\w|\$)+\s*$/; - -// JavaScript micro-templating, similar to John Resig's implementation. -// Underscore templating handles arbitrary delimiters, preserves whitespace, -// and correctly escapes quotes within interpolated code. -// NB: `oldSettings` only exists for backwards compatibility. -function template(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = defaults({}, settings, _$1.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - var argument = settings.variable; - if (argument) { - // Insure against third-party code injection. (CVE-2021-23358) - if (!bareIdentifier.test(argument)) throw new Error( - 'variable is not a bare identifier: ' + argument - ); - } else { - // If a variable is not specified, place data values in local scope. - source = 'with(obj||{}){\n' + source + '}\n'; - argument = 'obj'; - } - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(argument, '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _$1); - }; - - // Provide the compiled source as a convenience for precompilation. - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; -} - -// Traverses the children of `obj` along `path`. If a child is a function, it -// is invoked with its parent as context. Returns the value of the final -// child, or `fallback` if any child is undefined. -function result(obj, path, fallback) { - path = toPath(path); - var length = path.length; - if (!length) { - return isFunction$1(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); } - obj = isFunction$1(prop) ? prop.call(obj) : prop; - } - return obj; -} - -// Generate a unique integer id (unique within the entire client session). -// Useful for temporary DOM ids. -var idCounter = 0; -function uniqueId(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; -} - -// Start chaining a wrapped Underscore object. -function chain(obj) { - var instance = _$1(obj); - instance._chain = true; - return instance; -} - -// Internal function to execute `sourceFunc` bound to `context` with optional -// `args`. Determines whether to execute a function as a constructor or as a -// normal function. -function executeBound(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (isObject(result)) return result; - return self; -} - -// Partially apply a function by creating a version that has had some of its -// arguments pre-filled, without changing its dynamic `this` context. `_` acts -// as a placeholder by default, allowing any combination of arguments to be -// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. -var partial = restArguments(function(func, boundArgs) { - var placeholder = partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; -}); - -partial.placeholder = _$1; - -// Create a function bound to a given object (assigning `this`, and arguments, -// optionally). -var bind = restArguments(function(func, context, args) { - if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; -}); - -// Internal helper for collection methods to determine whether a collection -// should be iterated as an array or as an object. -// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength -// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 -var isArrayLike = createSizePropertyCheck(getLength); - -// Internal implementation of a recursive `flatten` function. -function flatten$1(input, depth, strict, output) { - output = output || []; - if (!depth && depth !== 0) { - depth = Infinity; - } else if (depth <= 0) { - return output.concat(input); - } - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { - // Flatten current level of array or arguments object. - if (depth > 1) { - flatten$1(value, depth - 1, strict, output); - idx = output.length; - } else { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); } - } - return output; -} - -// Bind a number of an object's methods to that object. Remaining arguments -// are the method names to be bound. Useful for ensuring that all callbacks -// defined on an object belong to it. -var bindAll = restArguments(function(obj, keys) { - keys = flatten$1(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = bind(obj[key], obj); - } - return obj; -}); - -// Memoize an expensive function by storing its results. -function memoize(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; -} - -// Delays a function for the given number of milliseconds, and then calls -// it with the arguments supplied. -var delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); -}); - -// Defers a function, scheduling it to run after the current call stack has -// cleared. -var defer = partial(delay, _$1, 1); - -// Returns a function, that, when invoked, will only be triggered at most once -// during a given window of time. Normally, the throttled function will run -// as much as it can, without ever going more than once per `wait` duration; -// but if you'd like to disable the execution on the leading edge, pass -// `{leading: false}`. To disable execution on the trailing edge, ditto. -function throttle(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var _now = now(); - if (!previous && options.leading === false) previous = _now; - var remaining = wait - (_now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = _now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; -} - -// When a sequence of calls of the returned function ends, the argument -// function is triggered. The end of a sequence is defined by the `wait` -// parameter. If `immediate` is passed, the argument function will be -// triggered at the beginning of the sequence instead of at the end. -function debounce(func, wait, immediate) { - var timeout, previous, args, result, context; - - var later = function() { - var passed = now() - previous; - if (wait > passed) { - timeout = setTimeout(later, wait - passed); - } else { - timeout = null; - if (!immediate) result = func.apply(context, args); - // This check is needed because `func` can recursively invoke `debounced`. - if (!timeout) args = context = null; + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - }; - - var debounced = restArguments(function(_args) { - context = this; - args = _args; - previous = now(); - if (!timeout) { - timeout = setTimeout(later, wait); - if (immediate) result = func.apply(context, args); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = args = context = null; - }; - - return debounced; -} - -// Returns the first function passed as an argument to the second, -// allowing you to adjust arguments, run code before and after, and -// conditionally execute the original function. -function wrap(func, wrapper) { - return partial(wrapper, func); -} - -// Returns a negated version of the passed-in predicate. -function negate(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} - -// Returns a function that is the composition of a list of functions, each -// consuming the return value of the function that follows. -function compose() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; -} - -// Returns a function that will only be executed on and after the Nth call. -function after(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - }; -} - -// Returns a function that will only be executed up to (but not including) the -// Nth call. -function before(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (times <= 1) func = null; - return memo; - }; -} - -// Returns a function that will be executed at most one time, no matter how -// often you call it. Useful for lazy initialization. -var once = partial(before, 2); - -// Returns the first key on an object that passes a truth test. -function findKey(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = keys(obj), key; - for (var i = 0, length = _keys.length; i < length; i++) { - key = _keys[i]; - if (predicate(obj[key], key, obj)) return key; - } -} - -// Internal function to generate `_.findIndex` and `_.findLastIndex`. -function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); } - return -1; - }; -} - -// Returns the first index on an array-like that passes a truth test. -var findIndex = createPredicateIndexFinder(1); - -// Returns the last index on an array-like that passes a truth test. -var findLastIndex = createPredicateIndexFinder(-1); - -// Use a comparator function to figure out the smallest index at which -// an object should be inserted so as to maintain order. Uses binary search. -function sortedIndex(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; -} - -// Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. -function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), isNaN$1); - return idx >= 0 ? idx + i : -1; + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - return -1; - }; } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -// Return the position of the first occurrence of an item in an array, -// or -1 if the item is not included in the array. -// If the array is large and already in sort order, pass `true` -// for **isSorted** to use binary search. -var indexOf = createIndexFinder(1, findIndex, sortedIndex); - -// Return the position of the last occurrence of an item in an array, -// or -1 if the item is not included in the array. -var lastIndexOf = createIndexFinder(-1, findLastIndex); - -// Return the first value which passes a truth test. -function find(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? findIndex : findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; -} -// Convenience version of a common use case of `_.find`: getting the first -// object containing specific `key:value` pairs. -function findWhere(obj, attrs) { - return find(obj, matcher(attrs)); -} +/***/ }), -// The cornerstone for collection functions, an `each` -// implementation, aka `forEach`. -// Handles raw objects in addition to array-likes. Treats all -// sparse array-likes as if they were dense. -function each(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var _keys = keys(obj); - for (i = 0, length = _keys.length; i < length; i++) { - iteratee(obj[_keys[i]], _keys[i], obj); - } - } - return obj; -} +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { -// Return the results of applying the iteratee to each element. -function map(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Internal helper to create a reducing function, iterating left or right. -function createReduce(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[_keys ? _keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = _keys ? _keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; +"use strict"; - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -// **Reduce** builds up a single result from a list of values, aka `inject`, -// or `foldl`. -var reduce = createReduce(1); -// The right-associative version of reduce, also known as `foldr`. -var reduceRight = createReduce(-1); - -// Return all the elements that pass a truth test. -function filter(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; -} +/***/ }), -// Return all the elements for which a truth test fails. -function reject(obj, predicate, context) { - return filter(obj, negate(cb(predicate)), context); -} +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { -// Determine whether all of the elements pass a truth test. -function every(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; -} +"use strict"; -// Determine if at least one element in the object passes a truth test. -function some(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; -// Determine if the array or object contains a given item (using `===`). -function contains(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return indexOf(obj, item, fromIndex) >= 0; -} -// Invoke a method (with arguments) on every item in a collection. -var invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (isFunction$1(path)) { - func = path; - } else { - path = toPath(path); - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); -}); +/***/ }), -// Convenience version of a common use case of `_.map`: fetching a property. -function pluck(obj, key) { - return map(obj, property(key)); -} +/***/ 2877: +/***/ ((module) => { -// Convenience version of a common use case of `_.filter`: selecting only -// objects containing specific `key:value` pairs. -function where(obj, attrs) { - return filter(obj, matcher(attrs)); -} +module.exports = eval("require")("encoding"); -// Return the maximum element (or element-based computation). -function max(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} -// Return the minimum element (or element-based computation). -function min(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || (computed === Infinity && result === Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} +/***/ }), -// Safely create a real, live array from anything iterable. -var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; -function toArray(obj) { - if (!obj) return []; - if (isArray(obj)) return slice.call(obj); - if (isString(obj)) { - // Keep surrogate pair characters together. - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return map(obj, identity); - return values(obj); -} +/***/ 9491: +/***/ ((module) => { -// Sample **n** random values from a collection using the modern version of the -// [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). -// If **n** is not specified, returns a single random element. -// The internal `guard` argument allows it to work with `_.map`. -function sample(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = values(obj); - return obj[random(obj.length - 1)]; - } - var sample = toArray(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); -} +"use strict"; +module.exports = require("assert"); -// Shuffle a collection. -function shuffle(obj) { - return sample(obj, Infinity); -} +/***/ }), -// Sort the object's values by a criterion produced by an iteratee. -function sortBy(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return pluck(map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); -} - -// An internal function used for aggregate "group by" operations. -function group(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; -} +/***/ 6113: +/***/ ((module) => { -// Groups the object's values by a criterion. Pass either a string attribute -// to group by, or a function that returns the criterion. -var groupBy = group(function(result, value, key) { - if (has$1(result, key)) result[key].push(value); else result[key] = [value]; -}); +"use strict"; +module.exports = require("crypto"); -// Indexes the object's values by a criterion, similar to `_.groupBy`, but for -// when you know that your index values will be unique. -var indexBy = group(function(result, value, key) { - result[key] = value; -}); +/***/ }), -// Counts instances of an object that group by a certain criterion. Pass -// either a string attribute to count by, or a function that returns the -// criterion. -var countBy = group(function(result, value, key) { - if (has$1(result, key)) result[key]++; else result[key] = 1; -}); +/***/ 2361: +/***/ ((module) => { -// Split a collection into two arrays: one whose elements all pass the given -// truth test, and one whose elements all do not pass the truth test. -var partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); -}, true); +"use strict"; +module.exports = require("events"); -// Return the number of elements in a collection. -function size(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : keys(obj).length; -} +/***/ }), -// Internal `_.pick` helper function to determine whether `key` is an enumerable -// property name of `obj`. -function keyInObj(value, key, obj) { - return key in obj; -} +/***/ 7147: +/***/ ((module) => { -// Return a copy of the object only containing the allowed properties. -var pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (isFunction$1(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten$1(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; -}); +"use strict"; +module.exports = require("fs"); -// Return a copy of the object without the disallowed properties. -var omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (isFunction$1(iteratee)) { - iteratee = negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = map(flatten$1(keys, false, false), String); - iteratee = function(value, key) { - return !contains(keys, key); - }; - } - return pick(obj, iteratee, context); -}); +/***/ }), -// Returns everything but the last entry of the array. Especially useful on -// the arguments object. Passing **n** will return all the values in -// the array, excluding the last N. -function initial(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); -} +/***/ 3685: +/***/ ((module) => { -// Get the first element of an array. Passing **n** will return the first N -// values in the array. The **guard** check allows it to work with `_.map`. -function first(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[0]; - return initial(array, array.length - n); -} +"use strict"; +module.exports = require("http"); -// Returns everything but the first entry of the `array`. Especially useful on -// the `arguments` object. Passing an **n** will return the rest N values in the -// `array`. -function rest(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); -} +/***/ }), -// Get the last element of an array. Passing **n** will return the last N -// values in the array. -function last(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return rest(array, Math.max(0, array.length - n)); -} +/***/ 5687: +/***/ ((module) => { -// Trim out all falsy values from an array. -function compact(array) { - return filter(array, Boolean); -} +"use strict"; +module.exports = require("https"); -// Flatten out an array, either recursively (by default), or up to `depth`. -// Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. -function flatten(array, depth) { - return flatten$1(array, depth, false); -} +/***/ }), -// Take the difference between one array and a number of other arrays. -// Only the elements present in just the first array will remain. -var difference = restArguments(function(array, rest) { - rest = flatten$1(rest, true, true); - return filter(array, function(value){ - return !contains(rest, value); - }); -}); +/***/ 1808: +/***/ ((module) => { -// Return a version of the array that does not contain the specified value(s). -var without = restArguments(function(array, otherArrays) { - return difference(array, otherArrays); -}); +"use strict"; +module.exports = require("net"); -// Produce a duplicate-free version of the array. If the array has already -// been sorted, you have the option of using a faster algorithm. -// The faster algorithm will not work with an iteratee if the iteratee -// is not a one-to-one function, so providing an iteratee will disable -// the faster algorithm. -function uniq(array, isSorted, iteratee, context) { - if (!isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!contains(result, value)) { - result.push(value); - } - } - return result; -} +/***/ }), -// Produce an array that contains the union: each distinct element from all of -// the passed-in arrays. -var union = restArguments(function(arrays) { - return uniq(flatten$1(arrays, true, true)); -}); +/***/ 2037: +/***/ ((module) => { -// Produce an array that contains every item shared between all the -// passed-in arrays. -function intersection(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; -} +"use strict"; +module.exports = require("os"); -// Complement of zip. Unzip accepts an array of arrays and groups -// each array's elements on shared indices. -function unzip(array) { - var length = (array && max(array, getLength).length) || 0; - var result = Array(length); +/***/ }), - for (var index = 0; index < length; index++) { - result[index] = pluck(array, index); - } - return result; -} +/***/ 1017: +/***/ ((module) => { -// Zip together multiple lists into a single array -- elements that share -// an index go together. -var zip = restArguments(unzip); +"use strict"; +module.exports = require("path"); -// Converts lists into objects. Pass either a single array of `[key, value]` -// pairs, or two parallel arrays of the same length -- one of keys, and one of -// the corresponding values. Passing by pairs is the reverse of `_.pairs`. -function object(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; -} +/***/ }), -// Generate an integer Array containing an arithmetic progression. A port of -// the native Python `range()` function. See -// [the Python documentation](https://docs.python.org/library/functions.html#range). -function range(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } +/***/ 5477: +/***/ ((module) => { - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); +"use strict"; +module.exports = require("punycode"); - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } +/***/ }), - return range; -} +/***/ 2781: +/***/ ((module) => { -// Chunk a single array into multiple arrays, each containing `count` or fewer -// items. -function chunk(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; -} +"use strict"; +module.exports = require("stream"); -// Helper function to continue chaining intermediate results. -function chainResult(instance, obj) { - return instance._chain ? _$1(obj).chain() : obj; -} +/***/ }), -// Add your own custom functions to the Underscore object. -function mixin(obj) { - each(functions(obj), function(name) { - var func = _$1[name] = obj[name]; - _$1.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_$1, args)); - }; - }); - return _$1; -} - -// Add all mutator `Array` functions to the wrapper. -each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) { - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) { - delete obj[0]; - } - } - return chainResult(this, obj); - }; -}); +/***/ 4404: +/***/ ((module) => { -// Add all accessor `Array` functions to the wrapper. -each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) obj = method.apply(obj, arguments); - return chainResult(this, obj); - }; -}); +"use strict"; +module.exports = require("tls"); -// Named Exports - -var allExports = { - __proto__: null, - VERSION: VERSION, - restArguments: restArguments, - isObject: isObject, - isNull: isNull, - isUndefined: isUndefined, - isBoolean: isBoolean, - isElement: isElement, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isRegExp: isRegExp, - isError: isError, - isSymbol: isSymbol, - isArrayBuffer: isArrayBuffer, - isDataView: isDataView$1, - isArray: isArray, - isFunction: isFunction$1, - isArguments: isArguments$1, - isFinite: isFinite$1, - isNaN: isNaN$1, - isTypedArray: isTypedArray$1, - isEmpty: isEmpty, - isMatch: isMatch, - isEqual: isEqual, - isMap: isMap, - isWeakMap: isWeakMap, - isSet: isSet, - isWeakSet: isWeakSet, - keys: keys, - allKeys: allKeys, - values: values, - pairs: pairs, - invert: invert, - functions: functions, - methods: functions, - extend: extend, - extendOwn: extendOwn, - assign: extendOwn, - defaults: defaults, - create: create, - clone: clone, - tap: tap, - get: get, - has: has, - mapObject: mapObject, - identity: identity, - constant: constant, - noop: noop, - toPath: toPath$1, - property: property, - propertyOf: propertyOf, - matcher: matcher, - matches: matcher, - times: times, - random: random, - now: now, - escape: _escape, - unescape: _unescape, - templateSettings: templateSettings, - template: template, - result: result, - uniqueId: uniqueId, - chain: chain, - iteratee: iteratee, - partial: partial, - bind: bind, - bindAll: bindAll, - memoize: memoize, - delay: delay, - defer: defer, - throttle: throttle, - debounce: debounce, - wrap: wrap, - negate: negate, - compose: compose, - after: after, - before: before, - once: once, - findKey: findKey, - findIndex: findIndex, - findLastIndex: findLastIndex, - sortedIndex: sortedIndex, - indexOf: indexOf, - lastIndexOf: lastIndexOf, - find: find, - detect: find, - findWhere: findWhere, - each: each, - forEach: each, - map: map, - collect: map, - reduce: reduce, - foldl: reduce, - inject: reduce, - reduceRight: reduceRight, - foldr: reduceRight, - filter: filter, - select: filter, - reject: reject, - every: every, - all: every, - some: some, - any: some, - contains: contains, - includes: contains, - include: contains, - invoke: invoke, - pluck: pluck, - where: where, - max: max, - min: min, - shuffle: shuffle, - sample: sample, - sortBy: sortBy, - groupBy: groupBy, - indexBy: indexBy, - countBy: countBy, - partition: partition, - toArray: toArray, - size: size, - pick: pick, - omit: omit, - first: first, - head: first, - take: first, - initial: initial, - last: last, - rest: rest, - tail: rest, - drop: rest, - compact: compact, - flatten: flatten, - without: without, - uniq: uniq, - unique: uniq, - union: union, - intersection: intersection, - difference: difference, - unzip: unzip, - transpose: unzip, - zip: zip, - object: object, - range: range, - chunk: chunk, - mixin: mixin, - 'default': _$1 -}; +/***/ }), -// Default Export - -// Add all of the Underscore functions to the wrapper object. -var _ = mixin(allExports); -// Legacy Node.js API. -_._ = _; - -exports.VERSION = VERSION; -exports._ = _; -exports._escape = _escape; -exports._unescape = _unescape; -exports.after = after; -exports.allKeys = allKeys; -exports.before = before; -exports.bind = bind; -exports.bindAll = bindAll; -exports.chain = chain; -exports.chunk = chunk; -exports.clone = clone; -exports.compact = compact; -exports.compose = compose; -exports.constant = constant; -exports.contains = contains; -exports.countBy = countBy; -exports.create = create; -exports.debounce = debounce; -exports.defaults = defaults; -exports.defer = defer; -exports.delay = delay; -exports.difference = difference; -exports.each = each; -exports.every = every; -exports.extend = extend; -exports.extendOwn = extendOwn; -exports.filter = filter; -exports.find = find; -exports.findIndex = findIndex; -exports.findKey = findKey; -exports.findLastIndex = findLastIndex; -exports.findWhere = findWhere; -exports.first = first; -exports.flatten = flatten; -exports.functions = functions; -exports.get = get; -exports.groupBy = groupBy; -exports.has = has; -exports.identity = identity; -exports.indexBy = indexBy; -exports.indexOf = indexOf; -exports.initial = initial; -exports.intersection = intersection; -exports.invert = invert; -exports.invoke = invoke; -exports.isArguments = isArguments$1; -exports.isArray = isArray; -exports.isArrayBuffer = isArrayBuffer; -exports.isBoolean = isBoolean; -exports.isDataView = isDataView$1; -exports.isDate = isDate; -exports.isElement = isElement; -exports.isEmpty = isEmpty; -exports.isEqual = isEqual; -exports.isError = isError; -exports.isFinite = isFinite$1; -exports.isFunction = isFunction$1; -exports.isMap = isMap; -exports.isMatch = isMatch; -exports.isNaN = isNaN$1; -exports.isNull = isNull; -exports.isNumber = isNumber; -exports.isObject = isObject; -exports.isRegExp = isRegExp; -exports.isSet = isSet; -exports.isString = isString; -exports.isSymbol = isSymbol; -exports.isTypedArray = isTypedArray$1; -exports.isUndefined = isUndefined; -exports.isWeakMap = isWeakMap; -exports.isWeakSet = isWeakSet; -exports.iteratee = iteratee; -exports.keys = keys; -exports.last = last; -exports.lastIndexOf = lastIndexOf; -exports.map = map; -exports.mapObject = mapObject; -exports.matcher = matcher; -exports.max = max; -exports.memoize = memoize; -exports.min = min; -exports.mixin = mixin; -exports.negate = negate; -exports.noop = noop; -exports.now = now; -exports.object = object; -exports.omit = omit; -exports.once = once; -exports.pairs = pairs; -exports.partial = partial; -exports.partition = partition; -exports.pick = pick; -exports.pluck = pluck; -exports.property = property; -exports.propertyOf = propertyOf; -exports.random = random; -exports.range = range; -exports.reduce = reduce; -exports.reduceRight = reduceRight; -exports.reject = reject; -exports.rest = rest; -exports.restArguments = restArguments; -exports.result = result; -exports.sample = sample; -exports.shuffle = shuffle; -exports.size = size; -exports.some = some; -exports.sortBy = sortBy; -exports.sortedIndex = sortedIndex; -exports.tap = tap; -exports.template = template; -exports.templateSettings = templateSettings; -exports.throttle = throttle; -exports.times = times; -exports.toArray = toArray; -exports.toPath = toPath$1; -exports.union = union; -exports.uniq = uniq; -exports.uniqueId = uniqueId; -exports.unzip = unzip; -exports.values = values; -exports.where = where; -exports.without = without; -exports.wrap = wrap; -exports.zip = zip; -//# sourceMappingURL=underscore-node-f.cjs.map +/***/ 7310: +/***/ ((module) => { +"use strict"; +module.exports = require("url"); /***/ }), -/***/ 5067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -var underscoreNodeF = __nccwpck_require__(6717); +/***/ 3837: +/***/ ((module) => { +"use strict"; +module.exports = require("util"); +/***/ }), -module.exports = underscoreNodeF._; -//# sourceMappingURL=underscore-node.cjs.map +/***/ 9796: +/***/ ((module) => { +"use strict"; +module.exports = require("zlib"); /***/ }), @@ -16201,7 +12351,7 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"] /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module is referenced by other modules so it can't be inlined -/******/ var __webpack_exports__ = __nccwpck_require__(2759); +/******/ var __webpack_exports__ = __nccwpck_require__(2483); /******/ module.exports = __webpack_exports__; /******/ /******/ })() diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.js b/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts similarity index 76% rename from .github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.js rename to .github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts index d03a947cdec8..ec70d1123000 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts @@ -1,17 +1,16 @@ -const _ = require('underscore'); -const core = require('@actions/core'); -const {context} = require('@actions/github'); -const CONST = require('../../../libs/CONST'); -const ActionUtils = require('../../../libs/ActionUtils'); -const GithubUtils = require('../../../libs/GithubUtils'); +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +import core from '@actions/core'; +import {context} from '@actions/github'; +import * as ActionUtils from '@github/libs/ActionUtils'; +import CONST from '@github/libs/CONST'; +import GithubUtils from '@github/libs/GithubUtils'; + +type PlatformResult = 'success' | 'cancelled' | 'skipped' | 'failure'; /** * Return a nicely formatted message for the table based on the result of the GitHub action job - * - * @param {String} platformResult - * @returns {String} */ -function getDeployTableMessage(platformResult) { +function getDeployTableMessage(platformResult: PlatformResult): string { switch (platformResult) { case 'success': return `${platformResult} ✅`; @@ -27,46 +26,38 @@ function getDeployTableMessage(platformResult) { /** * Comment Single PR - * - * @param {Number} PR - * @param {String} message - * @returns {Promise} */ -async function commentPR(PR, message) { +async function commentPR(PR: number, message: string) { try { await GithubUtils.createComment(context.repo.repo, PR, message); console.log(`Comment created on #${PR} successfully 🎉`); } catch (err) { console.log(`Unable to write comment on #${PR} 😞`); - core.setFailed(err.message); + if (err instanceof Error) { + core.setFailed(err.message); + } } } const workflowURL = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; async function run() { - const prList = _.map(ActionUtils.getJSONInput('PR_LIST', {required: true}), (num) => Number.parseInt(num, 10)); + const prList = ActionUtils.getJSONInput('PR_LIST', {required: true}).map((num: string) => Number.parseInt(num, 10)); const isProd = ActionUtils.getJSONInput('IS_PRODUCTION_DEPLOY', {required: true}); const version = core.getInput('DEPLOY_VERSION', {required: true}); - const androidResult = getDeployTableMessage(core.getInput('ANDROID', {required: true})); - const desktopResult = getDeployTableMessage(core.getInput('DESKTOP', {required: true})); - const iOSResult = getDeployTableMessage(core.getInput('IOS', {required: true})); - const webResult = getDeployTableMessage(core.getInput('WEB', {required: true})); - - /** - * @param {String} deployer - * @param {String} deployVerb - * @param {String} prTitle - * @returns {String} - */ - function getDeployMessage(deployer, deployVerb, prTitle) { + const androidResult = getDeployTableMessage(core.getInput('ANDROID', {required: true}) as PlatformResult); + const desktopResult = getDeployTableMessage(core.getInput('DESKTOP', {required: true}) as PlatformResult); + const iOSResult = getDeployTableMessage(core.getInput('IOS', {required: true}) as PlatformResult); + const webResult = getDeployTableMessage(core.getInput('WEB', {required: true}) as PlatformResult); + + function getDeployMessage(deployer: string, deployVerb: string, prTitle?: string): string { let message = `🚀 [${deployVerb}](${workflowURL}) to ${isProd ? 'production' : 'staging'}`; message += ` by https://github.com/${deployer} in version: ${version} 🚀`; message += `\n\nplatform | result\n---|---\n🤖 android 🤖|${androidResult}\n🖥 desktop 🖥|${desktopResult}`; message += `\n🍎 iOS 🍎|${iOSResult}\n🕸 web 🕸|${webResult}`; - if (deployVerb === 'Cherry-picked' && !/no ?qa/gi.test(prTitle)) { + if (deployVerb === 'Cherry-picked' && !/no ?qa/gi.test(prTitle ?? '')) { // eslint-disable-next-line max-len message += '\n\n@Expensify/applauseleads please QA this PR and check it off on the [deploy checklist](https://github.com/Expensify/App/issues?q=is%3Aopen+is%3Aissue+label%3AStagingDeployCash) if it passes.'; @@ -83,7 +74,7 @@ async function run() { labels: CONST.LABELS.STAGING_DEPLOY, state: 'closed', }); - const previousChecklistID = _.first(deployChecklists).number; + const previousChecklistID = deployChecklists[0].number; // who closed the last deploy checklist? const deployer = await GithubUtils.getActorWhoClosedIssue(previousChecklistID); @@ -102,7 +93,7 @@ async function run() { repo: CONST.APP_REPO, per_page: 100, }); - const currentTag = _.find(recentTags, (tag) => tag.name === version); + const currentTag = recentTags.find((tag) => tag.name === version); if (!currentTag) { const err = `Could not find tag matching ${version}`; console.error(err); @@ -127,10 +118,10 @@ async function run() { repo: CONST.APP_REPO, pull_number: prNumber, }); - const deployer = isCP ? commit.committer.name : pr.merged_by.login; + const deployer = isCP ? commit.committer.name : pr.merged_by?.login; const title = pr.title; - const deployMessage = getDeployMessage(deployer, isCP ? 'Cherry-picked' : 'Deployed', title); + const deployMessage = deployer ? getDeployMessage(deployer, isCP ? 'Cherry-picked' : 'Deployed', title) : ''; await commentPR(prNumber, deployMessage); } } diff --git a/.github/actions/javascript/postTestBuildComment/index.js b/.github/actions/javascript/postTestBuildComment/index.js index 329e0d3aad5d..27214d85d18d 100644 --- a/.github/actions/javascript/postTestBuildComment/index.js +++ b/.github/actions/javascript/postTestBuildComment/index.js @@ -11,7 +11,7 @@ const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); const {context} = __nccwpck_require__(5438); const CONST = __nccwpck_require__(4097); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); /** * @returns {String} @@ -133,784 +133,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4970,3874 +4424,2264 @@ const Endpoints = { }, secretScanning: { getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; +const VERSION = "5.16.2"; - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; + if (!newMethods[scope]) { + newMethods[scope] = {}; + } - return Bottleneck; + const scopeMethods = newMethods[scope]; - }).call(commonjsGlobal); + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - var Bottleneck_1 = Bottleneck; + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); + } + } - var lib = Bottleneck_1; + return newMethods; +} - return lib; +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -}))); + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } -/***/ }), + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -"use strict"; + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!(alias in options)) { + options[alias] = options[name]; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + delete options[name]; + } + } - /* istanbul ignore next */ + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - this.name = 'Deprecation'; + return requestWithDefaults(...args); } + return Object.assign(withDecorations, requestWithDefaults); } -exports.Deprecation = Deprecation; - - -/***/ }), - -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); } +legacyRestEndpointMethods.VERSION = VERSION; -function isPlainObject(o) { - var ctor,prot; +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map - if (isObject(o) === false) return false; - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; +/***/ }), - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; - } +"use strict"; - // Most likely a plain Object - return true; -} -exports.isPlainObject = isPlainObject; +Object.defineProperty(exports, "__esModule", ({ value: true })); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -/***/ }), +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const VERSION = "4.1.0"; -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +const noop = () => Promise.resolve(); // @ts-expect-error -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; -module.exports = Hash; + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -/***/ }), + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - -/***/ }), + const req = state.global.key(state.id).schedule(jobOptions, request, options); -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (isGraphQL) { + const res = await req; -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + return req; +} -module.exports = Map; +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; +function routeMatcher(paths) { + // EXAMPLE. For the following paths: -/***/ }), + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } + return new RegExp(regex, "i"); } -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; +// @ts-expect-error -module.exports = MapCache; +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -/***/ }), +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!enabled) { + return {}; + } -var root = __nccwpck_require__(9882); + const common = { + connection, + timeout + }; -/** Built-in value references. */ -var Symbol = root.Symbol; + if (groups.global == null) { + createGroups(Bottleneck, common); + } -module.exports = Symbol; + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling -/***/ }), + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); + } -/***/ 4356: -/***/ ((module) => { + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} + events.on("rate-limit", state.onRateLimit); // @ts-expect-error -module.exports = arrayMap; + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/***/ }), + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -var eq = __nccwpck_require__(1901); + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; + return {}; + }(); + + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; } - } - return -1; + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = assocIndexOf; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5758: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) - var index = 0, - length = path.length; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) } -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +function HookCollection () { + var state = { + registry: {} + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return hook +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return HookCollection() } -module.exports = baseIsNative; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection -/***/ }), -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ }), -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +/***/ 5549: +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +module.exports = addHook; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} -module.exports = baseToString; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4670: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = register; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!options) { + options = {}; + } -var root = __nccwpck_require__(9882); + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -module.exports = coreJsData; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} /***/ }), -/***/ 2085: +/***/ 6819: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - +module.exports = removeHook; -/***/ }), +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + if (index === -1) { + return; + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + state.registry[name].splice(index, 1); } -module.exports = getNative; - /***/ }), -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13522,230 +11366,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), diff --git a/.github/actions/javascript/reopenIssueWithComment/index.js b/.github/actions/javascript/reopenIssueWithComment/index.js index 6a5f89badb5e..252e772359ac 100644 --- a/.github/actions/javascript/reopenIssueWithComment/index.js +++ b/.github/actions/javascript/reopenIssueWithComment/index.js @@ -28,557 +28,454 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); + if (options && options.trimWhitespace === false) { + return val; } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + finally { + endGroup(); } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); - } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); } - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map /***/ }), -/***/ 7351: +/***/ 717: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +// For internal use, subject to change. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -599,81 +496,130 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); const os = __importStar(__nccwpck_require__(2037)); +const uuid_1 = __nccwpck_require__(5840); const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); } -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; } -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.result.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } } -//# sourceMappingURL=command.js.map +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map /***/ }), -/***/ 2186: +/***/ 2981: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -697,6 +643,52 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -707,465 +699,390 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } /** - * A code indicating that the action was successful + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path */ - ExitCode[ExitCode["Success"] = 0] = "Success"; + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } /** - * A code indicating that the action was a failure + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; } - else { - command_1.issueCommand('add-path', {}, inputPath); + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); } - if (options && options.trimWhitespace === false) { - return val; + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; } - return inputs.map(input => input.trim()); -} -exports.getMultilineInput = getMultilineInput; -/** - * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. - * Support boolean input list: `true | True | TRUE | false | False | FALSE` . - * The return value is also in boolean type. - * ref: https://yaml.org/spec/1.2/spec.html#id2804923 - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns boolean - */ -function getBooleanInput(name, options) { - const trueValue = ['true', 'True', 'TRUE']; - const falseValue = ['false', 'False', 'FALSE']; - const val = getInput(name, options); - if (trueValue.includes(val)) - return true; - if (falseValue.includes(val)) - return false; - throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + - `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); -} -exports.getBooleanInput = getBooleanInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - const filePath = process.env['GITHUB_OUTPUT'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; } - process.stdout.write(os.EOL); - command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. - * - */ -function setCommandEcho(enabled) { - command_1.issue('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function error(message, properties = {}) { - command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.error = error; -/** - * Adds a warning issue - * @param message warning issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function warning(message, properties = {}) { - command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.warning = warning; -/** - * Adds a notice issue - * @param message notice issue message. Errors will be converted to string via toString() - * @param properties optional properties to add to the annotation. - */ -function notice(message, properties = {}) { - command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); -} -exports.notice = notice; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); -} -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - command_1.issue('group', name); -} -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - command_1.issue('endgroup'); -} -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); -} -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function saveState(name, value) { - const filePath = process.env['GITHUB_STATE'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; + } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); } - command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); -} -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; -} -exports.getState = getState; -function getIDToken(aud) { - return __awaiter(this, void 0, void 0, function* () { - return yield oidc_utils_1.OidcClient.getIDToken(aud); - }); } -exports.getIDToken = getIDToken; -/** - * Summary exports - */ -var summary_1 = __nccwpck_require__(1327); -Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); -/** - * @deprecated use core.summary - */ -var summary_2 = __nccwpck_require__(1327); -Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +const _summary = new Summary(); /** - * Path exports + * @deprecated use `core.summary` */ -var path_utils_1 = __nccwpck_require__(2981); -Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); -Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); -Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); -//# sourceMappingURL=core.js.map +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map /***/ }), -/***/ 717: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 5278: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -// For internal use, subject to change. -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ -const fs = __importStar(__nccwpck_require__(7147)); -const os = __importStar(__nccwpck_require__(2037)); -const uuid_1 = __nccwpck_require__(5840); -const utils_1 = __nccwpck_require__(5278); -function issueFileCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; - if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); - } - if (!fs.existsSync(filePath)) { - throw new Error(`Missing file at path: ${filePath}`); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; } - fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { - encoding: 'utf8' - }); -} -exports.issueFileCommand = issueFileCommand; -function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${uuid_1.v4()}`; - const convertedValue = utils_1.toCommandValue(value); - // These should realistically never happen, but just in case someone finds a - // way to exploit uuid generation let's not allow keys or values that contain - // the delimiter. - if (key.includes(delimiter)) { - throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + else if (typeof input === 'string' || input instanceof String) { + return input; } - if (convertedValue.includes(delimiter)) { - throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + return JSON.stringify(input); +} +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; } - return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; } -exports.prepareKeyValueMessage = prepareKeyValueMessage; -//# sourceMappingURL=file-command.js.map +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 8041: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +/***/ 4087: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.OidcClient = void 0; -const http_client_1 = __nccwpck_require__(6255); -const auth_1 = __nccwpck_require__(5526); -const core_1 = __nccwpck_require__(2186); -class OidcClient { - static createHttpClient(allowRetry = true, maxRetry = 10) { - const requestOptions = { - allowRetries: allowRetry, - maxRetries: maxRetry - }; - return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); - } - static getRequestToken() { - const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; - if (!token) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); - } - return token; - } - static getIDTokenUrl() { - const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; - if (!runtimeUrl) { - throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); +exports.Context = void 0; +const fs_1 = __nccwpck_require__(7147); +const os_1 = __nccwpck_require__(2037); +class Context { + /** + * Hydrate the context from the environment + */ + constructor() { + var _a, _b, _c; + this.payload = {}; + if (process.env.GITHUB_EVENT_PATH) { + if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { + this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); + } + else { + const path = process.env.GITHUB_EVENT_PATH; + process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); + } } - return runtimeUrl; + this.eventName = process.env.GITHUB_EVENT_NAME; + this.sha = process.env.GITHUB_SHA; + this.ref = process.env.GITHUB_REF; + this.workflow = process.env.GITHUB_WORKFLOW; + this.action = process.env.GITHUB_ACTION; + this.actor = process.env.GITHUB_ACTOR; + this.job = process.env.GITHUB_JOB; + this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); + this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); + this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; + this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; + this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; } - static getCall(id_token_url) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const httpclient = OidcClient.createHttpClient(); - const res = yield httpclient - .getJson(id_token_url) - .catch(error => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n - Error Message: ${error.result.message}`); - }); - const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; - if (!id_token) { - throw new Error('Response json body do not have ID Token field'); - } - return id_token; - }); + get issue() { + const payload = this.payload; + return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); } - static getIDToken(audience) { - return __awaiter(this, void 0, void 0, function* () { - try { - // New ID Token is requested from action service - let id_token_url = OidcClient.getIDTokenUrl(); - if (audience) { - const encodedAudience = encodeURIComponent(audience); - id_token_url = `${id_token_url}&audience=${encodedAudience}`; - } - core_1.debug(`ID token url is ${id_token_url}`); - const id_token = yield OidcClient.getCall(id_token_url); - core_1.setSecret(id_token); - return id_token; - } - catch (error) { - throw new Error(`Error message: ${error.message}`); - } - }); + get repo() { + if (process.env.GITHUB_REPOSITORY) { + const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); + return { owner, repo }; + } + if (this.payload.repository) { + return { + owner: this.payload.repository.owner.login, + repo: this.payload.repository.name + }; + } + throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); } } -exports.OidcClient = OidcClient; -//# sourceMappingURL=oidc-utils.js.map +exports.Context = Context; +//# sourceMappingURL=context.js.map /***/ }), -/***/ 2981: +/***/ 7914: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; @@ -1190,822 +1107,359 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; -const path = __importStar(__nccwpck_require__(1017)); -/** - * toPosixPath converts the given path to the posix form. On Windows, \\ will be - * replaced with /. - * - * @param pth. Path to transform. - * @return string Posix path. - */ -function toPosixPath(pth) { - return pth.replace(/[\\]/g, '/'); +exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; +const httpClient = __importStar(__nccwpck_require__(6255)); +function getAuthString(token, options) { + if (!token && !options.auth) { + throw new Error('Parameter token or opts.auth is required'); + } + else if (token && options.auth) { + throw new Error('Parameters token and opts.auth may not both be specified'); + } + return typeof options.auth === 'string' ? options.auth : `token ${token}`; } -exports.toPosixPath = toPosixPath; -/** - * toWin32Path converts the given path to the win32 form. On Linux, / will be - * replaced with \\. - * - * @param pth. Path to transform. - * @return string Win32 path. - */ -function toWin32Path(pth) { - return pth.replace(/[/]/g, '\\'); +exports.getAuthString = getAuthString; +function getProxyAgent(destinationUrl) { + const hc = new httpClient.HttpClient(); + return hc.getAgent(destinationUrl); } -exports.toWin32Path = toWin32Path; -/** - * toPlatformPath converts the given path to a platform-specific path. It does - * this by replacing instances of / and \ with the platform-specific path - * separator. - * - * @param pth The path to platformize. - * @return string The platform-specific path. - */ -function toPlatformPath(pth) { - return pth.replace(/[/\\]/g, path.sep); +exports.getProxyAgent = getProxyAgent; +function getApiBaseUrl() { + return process.env['GITHUB_API_URL'] || 'https://api.github.com'; } -exports.toPlatformPath = toPlatformPath; -//# sourceMappingURL=path-utils.js.map +exports.getApiBaseUrl = getApiBaseUrl; +//# sourceMappingURL=utils.js.map /***/ }), -/***/ 1327: +/***/ 3030: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; -const os_1 = __nccwpck_require__(2037); -const fs_1 = __nccwpck_require__(7147); -const { access, appendFile, writeFile } = fs_1.promises; -exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; -exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; -class Summary { - constructor() { - this._buffer = ''; - } - /** - * Finds the summary file path from the environment, rejects if env var is not found or file does not exist - * Also checks r/w permissions. - * - * @returns step summary file path - */ - filePath() { - return __awaiter(this, void 0, void 0, function* () { - if (this._filePath) { - return this._filePath; - } - const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; - if (!pathFromEnv) { - throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); - } - try { - yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); - } - catch (_a) { - throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); - } - this._filePath = pathFromEnv; - return this._filePath; - }); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const Utils = __importStar(__nccwpck_require__(7914)); +// octokit + plugins +const core_1 = __nccwpck_require__(8525); +const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); +const plugin_paginate_rest_1 = __nccwpck_require__(8945); +exports.context = new Context.Context(); +const baseUrl = Utils.getApiBaseUrl(); +exports.defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) } - /** - * Wraps content in an HTML tag, adding any HTML attributes - * - * @param {string} tag HTML tag to wrap - * @param {string | null} content content within the tag - * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add - * - * @returns {string} content wrapped in HTML element - */ - wrap(tag, content, attrs = {}) { - const htmlAttrs = Object.entries(attrs) - .map(([key, value]) => ` ${key}="${value}"`) - .join(''); - if (!content) { - return `<${tag}${htmlAttrs}>`; - } - return `<${tag}${htmlAttrs}>${content}`; +}; +exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); +/** + * Convience function to correctly format Octokit Options to pass into the constructor. + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +function getOctokitOptions(token, options) { + const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller + // Auth + const auth = Utils.getAuthString(token, opts); + if (auth) { + opts.auth = auth; } - /** - * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. - * - * @param {SummaryWriteOptions} [options] (optional) options for write operation - * - * @returns {Promise} summary instance - */ - write(options) { - return __awaiter(this, void 0, void 0, function* () { - const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); - const filePath = yield this.filePath(); - const writeFunc = overwrite ? writeFile : appendFile; - yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); - return this.emptyBuffer(); - }); + return opts; +} +exports.getOctokitOptions = getOctokitOptions; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 673: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; +const REGEX_IS_INSTALLATION = /^ghs_/; +const REGEX_IS_USER_TO_SERVER = /^ghu_/; +async function auth(token) { + const isApp = token.split(/\./).length === 3; + const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); + const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); + const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; + return { + type: "token", + token: token, + tokenType + }; +} + +/** + * Prefix token for usage in the Authorization header + * + * @param token OAuth token or JSON Web Token + */ +function withAuthorizationPrefix(token) { + if (token.split(/\./).length === 3) { + return `bearer ${token}`; + } + + return `token ${token}`; +} + +async function hook(token, request, route, parameters) { + const endpoint = request.endpoint.merge(route, parameters); + endpoint.headers.authorization = withAuthorizationPrefix(token); + return request(endpoint); +} + +const createTokenAuth = function createTokenAuth(token) { + if (!token) { + throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); + } + + if (typeof token !== "string") { + throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); + } + + token = token.replace(/^(token|bearer) +/i, ""); + return Object.assign(auth.bind(null, token), { + hook: hook.bind(null, token) + }); +}; + +exports.createTokenAuth = createTokenAuth; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 8525: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var universalUserAgent = __nccwpck_require__(5030); +var beforeAfterHook = __nccwpck_require__(3682); +var request = __nccwpck_require__(9353); +var graphql = __nccwpck_require__(6422); +var authToken = __nccwpck_require__(673); + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; } - /** - * Clears the summary buffer and wipes the summary file - * - * @returns {Summary} summary instance - */ - clear() { - return __awaiter(this, void 0, void 0, function* () { - return this.emptyBuffer().write({ overwrite: true }); - }); + } + + return target; +} + +const VERSION = "3.6.0"; + +const _excluded = ["authStrategy"]; +class Octokit { + constructor(options = {}) { + const hook = new beforeAfterHook.Collection(); + const requestDefaults = { + baseUrl: request.request.endpoint.DEFAULTS.baseUrl, + headers: {}, + request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type + hook: hook.bind(null, "request") + }), + mediaType: { + previews: [], + format: "" + } + }; // prepend default user agent with `options.userAgent` if set + + requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); + + if (options.baseUrl) { + requestDefaults.baseUrl = options.baseUrl; } - /** - * Returns the current summary buffer as a string - * - * @returns {string} string of summary buffer - */ - stringify() { - return this._buffer; - } - /** - * If the summary buffer is empty - * - * @returns {boolen} true if the buffer is empty - */ - isEmptyBuffer() { - return this._buffer.length === 0; - } - /** - * Resets the summary buffer without writing to summary file - * - * @returns {Summary} summary instance - */ - emptyBuffer() { - this._buffer = ''; - return this; - } - /** - * Adds raw text to the summary buffer - * - * @param {string} text content to add - * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) - * - * @returns {Summary} summary instance - */ - addRaw(text, addEOL = false) { - this._buffer += text; - return addEOL ? this.addEOL() : this; - } - /** - * Adds the operating system-specific end-of-line marker to the buffer - * - * @returns {Summary} summary instance - */ - addEOL() { - return this.addRaw(os_1.EOL); - } - /** - * Adds an HTML codeblock to the summary buffer - * - * @param {string} code content to render within fenced code block - * @param {string} lang (optional) language to syntax highlight code - * - * @returns {Summary} summary instance - */ - addCodeBlock(code, lang) { - const attrs = Object.assign({}, (lang && { lang })); - const element = this.wrap('pre', this.wrap('code', code), attrs); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML list to the summary buffer - * - * @param {string[]} items list of items to render - * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) - * - * @returns {Summary} summary instance - */ - addList(items, ordered = false) { - const tag = ordered ? 'ol' : 'ul'; - const listItems = items.map(item => this.wrap('li', item)).join(''); - const element = this.wrap(tag, listItems); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML table to the summary buffer - * - * @param {SummaryTableCell[]} rows table rows - * - * @returns {Summary} summary instance - */ - addTable(rows) { - const tableBody = rows - .map(row => { - const cells = row - .map(cell => { - if (typeof cell === 'string') { - return this.wrap('td', cell); - } - const { header, data, colspan, rowspan } = cell; - const tag = header ? 'th' : 'td'; - const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); - return this.wrap(tag, data, attrs); - }) - .join(''); - return this.wrap('tr', cells); - }) - .join(''); - const element = this.wrap('table', tableBody); - return this.addRaw(element).addEOL(); - } - /** - * Adds a collapsable HTML details element to the summary buffer - * - * @param {string} label text for the closed state - * @param {string} content collapsable content - * - * @returns {Summary} summary instance - */ - addDetails(label, content) { - const element = this.wrap('details', this.wrap('summary', label) + content); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML image tag to the summary buffer - * - * @param {string} src path to the image you to embed - * @param {string} alt text description of the image - * @param {SummaryImageOptions} options (optional) addition image attributes - * - * @returns {Summary} summary instance - */ - addImage(src, alt, options) { - const { width, height } = options || {}; - const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); - const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML section heading element - * - * @param {string} text heading text - * @param {number | string} [level=1] (optional) the heading level, default: 1 - * - * @returns {Summary} summary instance - */ - addHeading(text, level) { - const tag = `h${level}`; - const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) - ? tag - : 'h1'; - const element = this.wrap(allowedTag, text); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML thematic break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addSeparator() { - const element = this.wrap('hr', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML line break (
) to the summary buffer - * - * @returns {Summary} summary instance - */ - addBreak() { - const element = this.wrap('br', null); - return this.addRaw(element).addEOL(); - } - /** - * Adds an HTML blockquote to the summary buffer - * - * @param {string} text quote text - * @param {string} cite (optional) citation url - * - * @returns {Summary} summary instance - */ - addQuote(text, cite) { - const attrs = Object.assign({}, (cite && { cite })); - const element = this.wrap('blockquote', text, attrs); - return this.addRaw(element).addEOL(); + + if (options.previews) { + requestDefaults.mediaType.previews = options.previews; } - /** - * Adds an HTML anchor tag to the summary buffer - * - * @param {string} text link text/content - * @param {string} href hyperlink - * - * @returns {Summary} summary instance - */ - addLink(text, href) { - const element = this.wrap('a', text, { href }); - return this.addRaw(element).addEOL(); + + if (options.timeZone) { + requestDefaults.headers["time-zone"] = options.timeZone; } -} -const _summary = new Summary(); -/** - * @deprecated use `core.summary` - */ -exports.markdownSummary = _summary; -exports.summary = _summary; -//# sourceMappingURL=summary.js.map -/***/ }), + this.request = request.request.defaults(requestDefaults); + this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); + this.log = Object.assign({ + debug: () => {}, + info: () => {}, + warn: console.warn.bind(console), + error: console.error.bind(console) + }, options.log); + this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance + // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. + // (2) If only `options.auth` is set, use the default token authentication strategy. + // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. + // TODO: type `options.auth` based on `options.authStrategy`. -/***/ 5278: -/***/ ((__unused_webpack_module, exports) => { + if (!options.authStrategy) { + if (!options.auth) { + // (1) + this.auth = async () => ({ + type: "unauthenticated" + }); + } else { + // (2) + const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ -"use strict"; + hook.wrap("request", auth.hook); + this.auth = auth; + } + } else { + const { + authStrategy + } = options, + otherOptions = _objectWithoutProperties(options, _excluded); -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.toCommandProperties = exports.toCommandValue = void 0; -/** - * Sanitizes an input into a string so it can be passed into issueCommand safely - * @param input input to sanitize into a string - */ -function toCommandValue(input) { - if (input === null || input === undefined) { - return ''; - } - else if (typeof input === 'string' || input instanceof String) { - return input; - } - return JSON.stringify(input); -} -exports.toCommandValue = toCommandValue; -/** - * - * @param annotationProperties - * @returns The command properties to send with the actual annotation command - * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 - */ -function toCommandProperties(annotationProperties) { - if (!Object.keys(annotationProperties).length) { - return {}; - } - return { - title: annotationProperties.title, - file: annotationProperties.file, - line: annotationProperties.startLine, - endLine: annotationProperties.endLine, - col: annotationProperties.startColumn, - endColumn: annotationProperties.endColumn - }; -} -exports.toCommandProperties = toCommandProperties; -//# sourceMappingURL=utils.js.map + const auth = authStrategy(Object.assign({ + request: this.request, + log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. + octokit: this, + octokitOptions: otherOptions + }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ -/***/ }), + hook.wrap("request", auth.hook); + this.auth = auth; + } // apply plugins + // https://stackoverflow.com/a/16345172 -/***/ 4087: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -"use strict"; + const classConstructor = this.constructor; + classConstructor.plugins.forEach(plugin => { + Object.assign(this, plugin(this, options)); + }); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.Context = void 0; -const fs_1 = __nccwpck_require__(7147); -const os_1 = __nccwpck_require__(2037); -class Context { - /** - * Hydrate the context from the environment - */ - constructor() { - var _a, _b, _c; - this.payload = {}; - if (process.env.GITHUB_EVENT_PATH) { - if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { - this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); - } - else { - const path = process.env.GITHUB_EVENT_PATH; - process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); - } - } - this.eventName = process.env.GITHUB_EVENT_NAME; - this.sha = process.env.GITHUB_SHA; - this.ref = process.env.GITHUB_REF; - this.workflow = process.env.GITHUB_WORKFLOW; - this.action = process.env.GITHUB_ACTION; - this.actor = process.env.GITHUB_ACTOR; - this.job = process.env.GITHUB_JOB; - this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); - this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); - this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; - this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; - this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; - } - get issue() { - const payload = this.payload; - return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); - } - get repo() { - if (process.env.GITHUB_REPOSITORY) { - const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); - return { owner, repo }; - } - if (this.payload.repository) { - return { - owner: this.payload.repository.owner.login, - repo: this.payload.repository.name - }; + static defaults(defaults) { + const OctokitWithDefaults = class extends this { + constructor(...args) { + const options = args[0] || {}; + + if (typeof defaults === "function") { + super(defaults(options)); + return; } - throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); - } -} -exports.Context = Context; -//# sourceMappingURL=context.js.map -/***/ }), + super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { + userAgent: `${options.userAgent} ${defaults.userAgent}` + } : null)); + } -/***/ 7914: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + }; + return OctokitWithDefaults; + } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; -const httpClient = __importStar(__nccwpck_require__(6255)); -function getAuthString(token, options) { - if (!token && !options.auth) { - throw new Error('Parameter token or opts.auth is required'); - } - else if (token && options.auth) { - throw new Error('Parameters token and opts.auth may not both be specified'); - } - return typeof options.auth === 'string' ? options.auth : `token ${token}`; -} -exports.getAuthString = getAuthString; -function getProxyAgent(destinationUrl) { - const hc = new httpClient.HttpClient(); - return hc.getAgent(destinationUrl); -} -exports.getProxyAgent = getProxyAgent; -function getApiBaseUrl() { - return process.env['GITHUB_API_URL'] || 'https://api.github.com'; -} -exports.getApiBaseUrl = getApiBaseUrl; -//# sourceMappingURL=utils.js.map + static plugin(...newPlugins) { + var _a; -/***/ }), + const currentPlugins = this.plugins; + const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); + return NewOctokit; + } -/***/ 3030: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { +} +Octokit.VERSION = VERSION; +Octokit.plugins = []; -"use strict"; +exports.Octokit = Octokit; +//# sourceMappingURL=index.js.map -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(4087)); -const Utils = __importStar(__nccwpck_require__(7914)); -// octokit + plugins -const core_1 = __nccwpck_require__(8525); -const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); -const plugin_paginate_rest_1 = __nccwpck_require__(8945); -exports.context = new Context.Context(); -const baseUrl = Utils.getApiBaseUrl(); -exports.defaults = { - baseUrl, - request: { - agent: Utils.getProxyAgent(baseUrl) - } -}; -exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); -/** - * Convience function to correctly format Octokit Options to pass into the constructor. - * - * @param token the repo PAT or GITHUB_TOKEN - * @param options other options to set - */ -function getOctokitOptions(token, options) { - const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller - // Auth - const auth = Utils.getAuthString(token, opts); - if (auth) { - opts.auth = auth; - } - return opts; -} -exports.getOctokitOptions = getOctokitOptions; -//# sourceMappingURL=utils.js.map /***/ }), -/***/ 673: -/***/ ((__unused_webpack_module, exports) => { +/***/ 8713: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; -const REGEX_IS_INSTALLATION = /^ghs_/; -const REGEX_IS_USER_TO_SERVER = /^ghu_/; -async function auth(token) { - const isApp = token.split(/\./).length === 3; - const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); - const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); - const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; - return { - type: "token", - token: token, - tokenType - }; -} +var isPlainObject = __nccwpck_require__(3287); +var universalUserAgent = __nccwpck_require__(5030); -/** - * Prefix token for usage in the Authorization header - * - * @param token OAuth token or JSON Web Token - */ -function withAuthorizationPrefix(token) { - if (token.split(/\./).length === 3) { - return `bearer ${token}`; +function lowercaseKeys(object) { + if (!object) { + return {}; } - return `token ${token}`; -} - -async function hook(token, request, route, parameters) { - const endpoint = request.endpoint.merge(route, parameters); - endpoint.headers.authorization = withAuthorizationPrefix(token); - return request(endpoint); -} - -const createTokenAuth = function createTokenAuth(token) { - if (!token) { - throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); - } - - if (typeof token !== "string") { - throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); - } - - token = token.replace(/^(token|bearer) +/i, ""); - return Object.assign(auth.bind(null, token), { - hook: hook.bind(null, token) - }); -}; - -exports.createTokenAuth = createTokenAuth; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 8525: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -var universalUserAgent = __nccwpck_require__(5030); -var beforeAfterHook = __nccwpck_require__(3682); -var request = __nccwpck_require__(9353); -var graphql = __nccwpck_require__(6422); -var authToken = __nccwpck_require__(673); - -function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; - - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } - - return target; -} - -function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - - var target = _objectWithoutPropertiesLoose(source, excluded); - - var key, i; - - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } - - return target; -} - -const VERSION = "3.6.0"; - -const _excluded = ["authStrategy"]; -class Octokit { - constructor(options = {}) { - const hook = new beforeAfterHook.Collection(); - const requestDefaults = { - baseUrl: request.request.endpoint.DEFAULTS.baseUrl, - headers: {}, - request: Object.assign({}, options.request, { - // @ts-ignore internal usage only, no need to type - hook: hook.bind(null, "request") - }), - mediaType: { - previews: [], - format: "" - } - }; // prepend default user agent with `options.userAgent` if set - - requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); - - if (options.baseUrl) { - requestDefaults.baseUrl = options.baseUrl; - } - - if (options.previews) { - requestDefaults.mediaType.previews = options.previews; - } - - if (options.timeZone) { - requestDefaults.headers["time-zone"] = options.timeZone; - } - - this.request = request.request.defaults(requestDefaults); - this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); - this.log = Object.assign({ - debug: () => {}, - info: () => {}, - warn: console.warn.bind(console), - error: console.error.bind(console) - }, options.log); - this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance - // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. - // (2) If only `options.auth` is set, use the default token authentication strategy. - // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. - // TODO: type `options.auth` based on `options.authStrategy`. - - if (!options.authStrategy) { - if (!options.auth) { - // (1) - this.auth = async () => ({ - type: "unauthenticated" - }); - } else { - // (2) - const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } - } else { - const { - authStrategy - } = options, - otherOptions = _objectWithoutProperties(options, _excluded); - - const auth = authStrategy(Object.assign({ - request: this.request, - log: this.log, - // we pass the current octokit instance as well as its constructor options - // to allow for authentication strategies that return a new octokit instance - // that shares the same internal state as the current one. The original - // requirement for this was the "event-octokit" authentication strategy - // of https://github.com/probot/octokit-auth-probot. - octokit: this, - octokitOptions: otherOptions - }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ - - hook.wrap("request", auth.hook); - this.auth = auth; - } // apply plugins - // https://stackoverflow.com/a/16345172 - - - const classConstructor = this.constructor; - classConstructor.plugins.forEach(plugin => { - Object.assign(this, plugin(this, options)); - }); - } - - static defaults(defaults) { - const OctokitWithDefaults = class extends this { - constructor(...args) { - const options = args[0] || {}; - - if (typeof defaults === "function") { - super(defaults(options)); - return; - } - - super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { - userAgent: `${options.userAgent} ${defaults.userAgent}` - } : null)); - } - - }; - return OctokitWithDefaults; - } - /** - * Attach a plugin (or many) to your Octokit instance. - * - * @example - * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) - */ - - - static plugin(...newPlugins) { - var _a; - - const currentPlugins = this.plugins; - const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); - return NewOctokit; - } - -} -Octokit.VERSION = VERSION; -Octokit.plugins = []; - -exports.Octokit = Octokit; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 8713: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -var isPlainObject = __nccwpck_require__(3287); -var universalUserAgent = __nccwpck_require__(5030); - -function lowercaseKeys(object) { - if (!object) { - return {}; - } - - return Object.keys(object).reduce((newObj, key) => { - newObj[key.toLowerCase()] = object[key]; - return newObj; - }, {}); + return Object.keys(object).reduce((newObj, key) => { + newObj[key.toLowerCase()] = object[key]; + return newObj; + }, {}); } function mergeDeep(defaults, options) { @@ -4797,3898 +4251,2288 @@ const Endpoints = { updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], - updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; - - -/***/ }), - -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; } +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +"use strict"; -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = ListCache; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; -module.exports = Map; + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -/***/ }), + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; + const req = state.global.key(state.id).schedule(jobOptions, request, options); -/***/ }), + if (isGraphQL) { + const res = await req; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -var root = __nccwpck_require__(9882); + return req; +} -/** Built-in value references. */ -var Symbol = root.Symbol; +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -module.exports = Symbol; +function routeMatcher(paths) { + // EXAMPLE. For the following paths: + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: -/***/ }), + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -/***/ 4356: -/***/ ((module) => { + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + return new RegExp(regex, "i"); } -module.exports = arrayMap; - +// @ts-expect-error -/***/ }), +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -var eq = __nccwpck_require__(1901); +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } + if (!enabled) { + return {}; } - return -1; -} - -module.exports = assocIndexOf; + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); + } - var index = 0, - length = path.length; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -module.exports = baseGet; + events.on("rate-limit", state.onRateLimit); // @ts-expect-error + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -/***/ }), + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + return {}; + }(); -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; + } + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = baseGetTag; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 411: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseIsNative; - - -/***/ }), - -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +function HookCollection () { + var state = { + registry: {} + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; + return hook +} -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + return HookCollection() } -module.exports = baseToString; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 5549: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = addHook; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; + } -var root = __nccwpck_require__(9882); + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; + } -module.exports = coreJsData; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2085: +/***/ 4670: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; +module.exports = register; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); + } -/***/ }), + if (!options) { + options = {}; + } -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -var isKeyable = __nccwpck_require__(3308); + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); } -module.exports = getMapData; - /***/ }), -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); +/***/ 6819: +/***/ ((module) => { -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} +module.exports = removeHook; -module.exports = getNative; +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -/***/ }), + if (index === -1) { + return; + } -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + state.registry[name].splice(index, 1); +} -var Symbol = __nccwpck_require__(9213); -/** Used for built-in method references. */ -var objectProto = Object.prototype; +/***/ }), -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; -module.exports = getRawTag; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; + var parser = { + load: load, + overwrite: overwrite + }; -/***/ }), + var DLList; -/***/ 3542: -/***/ ((module) => { + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } -module.exports = getValue; + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ }), + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -var nativeCreate = __nccwpck_require__(3041); + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + }; -module.exports = hashClear; + var DLList_1 = DLList; + var Events; -/***/ }), + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/***/ 712: -/***/ ((module) => { + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } -module.exports = hashDelete; + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } + }; -/***/ }), + var Events_1 = Events; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var DLList$1, Events$1, Queues; -var nativeCreate = __nccwpck_require__(3041); + DLList$1 = DLList_1; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + Events$1 = Events_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } -module.exports = hashGet; + push(job) { + return this._lists[job.options.priority].push(job); + } + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ }), + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -var nativeCreate = __nccwpck_require__(3041); + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + }; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var Queues_1 = Queues; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var BottleneckError; -module.exports = hashHas; + BottleneckError = class BottleneckError extends Error {}; + var BottleneckError_1 = BottleneckError; -/***/ }), + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + NUM_PRIORITIES = 10; -var nativeCreate = __nccwpck_require__(3041); + DEFAULT_PRIORITY = 5; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + parser$1 = parser; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + BottleneckError$1 = BottleneckError_1; -module.exports = hashSet; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ }), + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } -module.exports = isKey; + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ }), + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/***/ 3308: -/***/ ((module) => { + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } -module.exports = isKeyable; + }; + var Job_1 = Job; -/***/ }), + var BottleneckError$2, LocalDatastore, parser$2; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + parser$2 = parser; -var coreJsData = __nccwpck_require__(8380); + BottleneckError$2 = BottleneckError_1; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } -module.exports = isMasked; + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ }), + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/***/ 9792: -/***/ ((module) => { + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } -module.exports = listCacheClear; + async __running__() { + await this.yieldLoop(); + return this._running; + } + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ }), + async __done__() { + await this.yieldLoop(); + return this._done; + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -var assocIndexOf = __nccwpck_require__(6752); + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** Built-in value references. */ -var splice = arrayProto.splice; + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + isBlocked(now) { + return this._unblockTime >= now; + } -module.exports = listCacheDelete; + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ }), + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -var assocIndexOf = __nccwpck_require__(6752); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } - return index < 0 ? undefined : data[index][1]; -} + }; -module.exports = listCacheGet; + var LocalDatastore_1 = LocalDatastore; + var BottleneckError$3, States; -/***/ }), + BottleneckError$3 = BottleneckError_1; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -var assocIndexOf = __nccwpck_require__(6752); + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } -module.exports = listCacheHas; + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ }), + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -var assocIndexOf = __nccwpck_require__(6752); + }; -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + var States_1 = States; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var DLList$2, Sync; -module.exports = listCacheSet; + DLList$2 = DLList_1; + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ }), + isEmpty() { + return this._queue.length === 0; + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + }; -module.exports = mapCacheClear; + var Sync_1 = Sync; + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ }), + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getMapData = __nccwpck_require__(9980); + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; + parser$3 = parser; -/***/ }), + Events$2 = Events_1; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + RedisConnection$1 = require$$2; -var getMapData = __nccwpck_require__(9980); + IORedisConnection$1 = require$$3; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + Scripts$1 = require$$4; -module.exports = mapCacheGet; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ }), + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -var getMapData = __nccwpck_require__(9980); + keys() { + return Object.keys(this.instances); + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13528,2387 +11372,690 @@ function validate(uuid) { return typeof uuid === 'string' && _regex.default.test(uuid); } -var _default = validate; -exports["default"] = _default; - -/***/ }), - -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} - - -/***/ }), - -/***/ 2877: -/***/ ((module) => { - -module.exports = eval("require")("encoding"); - - -/***/ }), - -/***/ 9491: -/***/ ((module) => { - -"use strict"; -module.exports = require("assert"); - -/***/ }), - -/***/ 6113: -/***/ ((module) => { - -"use strict"; -module.exports = require("crypto"); - -/***/ }), - -/***/ 2361: -/***/ ((module) => { - -"use strict"; -module.exports = require("events"); - -/***/ }), - -/***/ 7147: -/***/ ((module) => { - -"use strict"; -module.exports = require("fs"); - -/***/ }), - -/***/ 3685: -/***/ ((module) => { - -"use strict"; -module.exports = require("http"); - -/***/ }), - -/***/ 5687: -/***/ ((module) => { - -"use strict"; -module.exports = require("https"); - -/***/ }), - -/***/ 1808: -/***/ ((module) => { - -"use strict"; -module.exports = require("net"); - -/***/ }), - -/***/ 2037: -/***/ ((module) => { - -"use strict"; -module.exports = require("os"); - -/***/ }), - -/***/ 1017: -/***/ ((module) => { - -"use strict"; -module.exports = require("path"); - -/***/ }), - -/***/ 5477: -/***/ ((module) => { - -"use strict"; -module.exports = require("punycode"); - -/***/ }), - -/***/ 2781: -/***/ ((module) => { - -"use strict"; -module.exports = require("stream"); - -/***/ }), - -/***/ 4404: -/***/ ((module) => { - -"use strict"; -module.exports = require("tls"); - -/***/ }), - -/***/ 7310: -/***/ ((module) => { - -"use strict"; -module.exports = require("url"); - -/***/ }), - -/***/ 3837: -/***/ ((module) => { - -"use strict"; -module.exports = require("util"); - -/***/ }), - -/***/ 9796: -/***/ ((module) => { - -"use strict"; -module.exports = require("zlib"); - -/***/ }), - -/***/ 6717: -/***/ ((__unused_webpack_module, exports) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -// Current version. -var VERSION = '1.13.6'; - -// Establish the root object, `window` (`self`) in the browser, `global` -// on the server, or `this` in some virtual machines. We use `self` -// instead of `window` for `WebWorker` support. -var root = (typeof self == 'object' && self.self === self && self) || - (typeof global == 'object' && global.global === global && global) || - Function('return this')() || - {}; - -// Save bytes in the minified (but not gzipped) version: -var ArrayProto = Array.prototype, ObjProto = Object.prototype; -var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - -// Create quick reference variables for speed access to core prototypes. -var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - -// Modern feature detection. -var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', - supportsDataView = typeof DataView !== 'undefined'; - -// All **ECMAScript 5+** native function implementations that we hope to use -// are declared here. -var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create, - nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; - -// Create references to these builtin functions because we override them. -var _isNaN = isNaN, - _isFinite = isFinite; - -// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. -var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); -var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - -// The largest integer that can be represented exactly. -var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - -// Some functions take a variable number of arguments, or a few expected -// arguments at the beginning and then a variable number of values to operate -// on. This helper accumulates all remaining arguments past the function’s -// argument length (or an explicit `startIndex`), into an array that becomes -// the last argument. Similar to ES6’s "rest parameter". -function restArguments(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; -} - -// Is a given variable an object? -function isObject(obj) { - var type = typeof obj; - return type === 'function' || (type === 'object' && !!obj); -} - -// Is a given value equal to null? -function isNull(obj) { - return obj === null; -} - -// Is a given variable undefined? -function isUndefined(obj) { - return obj === void 0; -} - -// Is a given value a boolean? -function isBoolean(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; -} - -// Is a given value a DOM element? -function isElement(obj) { - return !!(obj && obj.nodeType === 1); -} - -// Internal function for creating a `toString`-based type tester. -function tagTester(name) { - var tag = '[object ' + name + ']'; - return function(obj) { - return toString.call(obj) === tag; - }; -} - -var isString = tagTester('String'); - -var isNumber = tagTester('Number'); - -var isDate = tagTester('Date'); - -var isRegExp = tagTester('RegExp'); - -var isError = tagTester('Error'); - -var isSymbol = tagTester('Symbol'); - -var isArrayBuffer = tagTester('ArrayBuffer'); - -var isFunction = tagTester('Function'); - -// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old -// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). -var nodelist = root.document && root.document.childNodes; -if ( true && typeof Int8Array != 'object' && typeof nodelist != 'function') { - isFunction = function(obj) { - return typeof obj == 'function' || false; - }; -} - -var isFunction$1 = isFunction; - -var hasObjectTag = tagTester('Object'); +var _default = validate; +exports["default"] = _default; -// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. -// In IE 11, the most common among them, this problem also applies to -// `Map`, `WeakMap` and `Set`. -var hasStringTagBug = ( - supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) - ), - isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); +/***/ }), -var isDataView = tagTester('DataView'); +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// In IE 10 - Edge 13, we need a different heuristic -// to determine whether an object is a `DataView`. -function ie10IsDataView(obj) { - return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); -} +"use strict"; -var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); -// Is a given value an array? -// Delegates to ECMA5's native `Array.isArray`. -var isArray = nativeIsArray || tagTester('Array'); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -// Internal function to check whether `key` is an own property name of `obj`. -function has$1(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); -} +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -var isArguments = tagTester('Arguments'); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// Define a fallback version of the method in browsers (ahem, IE < 9), where -// there isn't any inspectable "Arguments" type. -(function() { - if (!isArguments(arguments)) { - isArguments = function(obj) { - return has$1(obj, 'callee'); - }; +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); } -}()); - -var isArguments$1 = isArguments; - -// Is a given object a finite number? -function isFinite$1(obj) { - return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); -} - -// Is the given value `NaN`? -function isNaN$1(obj) { - return isNumber(obj) && _isNaN(obj); -} -// Predicate-generating function. Often useful outside of Underscore. -function constant(value) { - return function() { - return value; - }; + return parseInt(uuid.substr(14, 1), 16); } -// Common internal logic for `isArrayLike` and `isBufferLike`. -function createSizePropertyCheck(getSizeProperty) { - return function(collection) { - var sizeProperty = getSizeProperty(collection); - return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; - } -} +var _default = version; +exports["default"] = _default; -// Internal helper to generate a function to obtain property `key` from `obj`. -function shallowProperty(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; -} +/***/ }), -// Internal helper to obtain the `byteLength` property of an object. -var getByteLength = shallowProperty('byteLength'); +/***/ 2940: +/***/ ((module) => { -// Internal helper to determine whether we should spend extensive checks against -// `ArrayBuffer` et al. -var isBufferLike = createSizePropertyCheck(getByteLength); +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) -// Is a given value a typed array? -var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; -function isTypedArray(obj) { - // `ArrayBuffer.isView` is the most future-proof, so use it when available. - // Otherwise, fall back on the above regular expression. - return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : - isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); -} + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) -// Internal helper to obtain the `length` property of an object. -var getLength = shallowProperty('length'); + return wrapper -// Internal helper to create a simple lookup structure. -// `collectNonEnumProps` used to depend on `_.contains`, but this led to -// circular imports. `emulatedSet` is a one-off solution that only works for -// arrays of strings. -function emulatedSet(keys) { - var hash = {}; - for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; - return { - contains: function(key) { return hash[key] === true; }, - push: function(key) { - hash[key] = true; - return keys.push(key); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] } - }; + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } } -// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't -// be iterated by `for key in ...` and thus missed. Extends `keys` in place if -// needed. -function collectNonEnumProps(obj, keys) { - keys = emulatedSet(keys); - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto; - // Constructor is a special case. - var prop = 'constructor'; - if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { - keys.push(prop); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); } - } -} - -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native `Object.keys`. -function keys(obj) { - if (!isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has$1(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -function isEmpty(obj) { - if (obj == null) return true; - // Skip the more expensive `toString`-based type checks if `obj` has no - // `.length`. - var length = getLength(obj); - if (typeof length == 'number' && ( - isArray(obj) || isString(obj) || isArguments$1(obj) - )) return length === 0; - return getLength(keys(obj)) === 0; -} - -// Returns whether an object has a given set of `key:value` pairs. -function isMatch(object, attrs) { - var _keys = keys(attrs), length = _keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = _keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; -} - -// If Underscore is called as a function, it returns a wrapped object that can -// be used OO-style. This wrapper holds altered versions of all functions added -// through `_.mixin`. Wrapped objects may be chained. -function _$1(obj) { - if (obj instanceof _$1) return obj; - if (!(this instanceof _$1)) return new _$1(obj); - this._wrapped = obj; -} - -_$1.VERSION = VERSION; - -// Extracts the result from a wrapped and chained object. -_$1.prototype.value = function() { - return this._wrapped; -}; - -// Provide unwrapping proxies for some methods used in engine operations -// such as arithmetic and JSON stringification. -_$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; - -_$1.prototype.toString = function() { - return String(this._wrapped); -}; - -// Internal function to wrap or shallow-copy an ArrayBuffer, -// typed array or DataView to a new view, reusing the buffer. -function toBufferView(bufferSource) { - return new Uint8Array( - bufferSource.buffer || bufferSource, - bufferSource.byteOffset || 0, - getByteLength(bufferSource) - ); -} - -// We use this string twice, so give it a name for minification. -var tagDataView = '[object DataView]'; - -// Internal recursive comparison function for `_.isEqual`. -function eq(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -// Internal recursive comparison function for `_.isEqual`. -function deepEq(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _$1) a = a._wrapped; - if (b instanceof _$1) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - // Work around a bug in IE 10 - Edge 13. - if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { - if (!isDataView$1(b)) return false; - className = tagDataView; - } - switch (className) { - // These types are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - case '[object ArrayBuffer]': - case tagDataView: - // Coerce to typed array so we can fall through. - return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); - } - - var areArrays = className === '[object Array]'; - if (!areArrays && isTypedArray$1(a)) { - var byteLength = getByteLength(a); - if (byteLength !== getByteLength(b)) return false; - if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; - areArrays = true; - } - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && - isFunction$1(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); } - } else { - // Deep compare objects. - var _keys = keys(a), key; - length = _keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = _keys[length]; - if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -// Perform a deep comparison to check if two objects are equal. -function isEqual(a, b) { - return eq(a, b); -} - -// Retrieve all the enumerable property names of an object. -function allKeys(obj) { - if (!isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Since the regular `Object.prototype.toString` type tests don't work for -// some types in IE 11, we use a fingerprinting heuristic instead, based -// on the methods. It's not great, but it's the best we got. -// The fingerprint method lists are defined below. -function ie11fingerprint(methods) { - var length = getLength(methods); - return function(obj) { - if (obj == null) return false; - // `Map`, `WeakMap` and `Set` have no enumerable keys. - var keys = allKeys(obj); - if (getLength(keys)) return false; - for (var i = 0; i < length; i++) { - if (!isFunction$1(obj[methods[i]])) return false; - } - // If we are testing against `WeakMap`, we need to ensure that - // `obj` doesn't have a `forEach` method in order to distinguish - // it from a regular `Map`. - return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); - }; -} - -// In the interest of compact minification, we write -// each string in the fingerprints only once. -var forEachName = 'forEach', - hasName = 'has', - commonInit = ['clear', 'delete'], - mapTail = ['get', hasName, 'set']; - -// `Map`, `WeakMap` and `Set` each have slightly different -// combinations of the above sublists. -var mapMethods = commonInit.concat(forEachName, mapTail), - weakMapMethods = commonInit.concat(mapTail), - setMethods = ['add'].concat(commonInit, forEachName, hasName); - -var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); - -var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); - -var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); - -var isWeakSet = tagTester('WeakSet'); - -// Retrieve the values of an object's properties. -function values(obj) { - var _keys = keys(obj); - var length = _keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[_keys[i]]; - } - return values; -} - -// Convert an object into a list of `[key, value]` pairs. -// The opposite of `_.object` with one argument. -function pairs(obj) { - var _keys = keys(obj); - var length = _keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [_keys[i], obj[_keys[i]]]; - } - return pairs; -} - -// Invert the keys and values of an object. The values must be serializable. -function invert(obj) { - var result = {}; - var _keys = keys(obj); - for (var i = 0, length = _keys.length; i < length; i++) { - result[obj[_keys[i]]] = _keys[i]; - } - return result; -} - -// Return a sorted list of the function names available on the object. -function functions(obj) { - var names = []; - for (var key in obj) { - if (isFunction$1(obj[key])) names.push(key); - } - return names.sort(); -} - -// An internal function for creating assigner functions. -function createAssigner(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); } - return obj; - }; -} - -// Extend a given object with all the properties in passed-in object(s). -var extend = createAssigner(allKeys); - -// Assigns a given object with all the own properties in the passed-in -// object(s). -// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) -var extendOwn = createAssigner(keys); - -// Fill in a given object with default properties. -var defaults = createAssigner(allKeys, true); - -// Create a naked function reference for surrogate-prototype-swapping. -function ctor() { - return function(){}; -} - -// An internal function for creating a new object that inherits from another. -function baseCreate(prototype) { - if (!isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - var Ctor = ctor(); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; -} - -// Creates an object that inherits from the given prototype object. -// If additional properties are provided then they will be added to the -// created object. -function create(prototype, props) { - var result = baseCreate(prototype); - if (props) extendOwn(result, props); - return result; -} - -// Create a (shallow-cloned) duplicate of an object. -function clone(obj) { - if (!isObject(obj)) return obj; - return isArray(obj) ? obj.slice() : extend({}, obj); -} - -// Invokes `interceptor` with the `obj` and then returns `obj`. -// The primary purpose of this method is to "tap into" a method chain, in -// order to perform operations on intermediate results within the chain. -function tap(obj, interceptor) { - interceptor(obj); - return obj; -} - -// Normalize a (deep) property `path` to array. -// Like `_.iteratee`, this function can be customized. -function toPath$1(path) { - return isArray(path) ? path : [path]; -} -_$1.toPath = toPath$1; - -// Internal wrapper for `_.toPath` to enable minification. -// Similar to `cb` for `_.iteratee`. -function toPath(path) { - return _$1.toPath(path); -} - -// Internal function to obtain a nested property in `obj` along `path`. -function deepGet(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; -} - -// Get the value of the (deep) property on `path` from `object`. -// If any property in `path` does not exist or if the value is -// `undefined`, return `defaultValue` instead. -// The `path` is normalized through `_.toPath`. -function get(object, path, defaultValue) { - var value = deepGet(object, toPath(path)); - return isUndefined(value) ? defaultValue : value; -} - -// Shortcut function for checking if an object has a given property directly on -// itself (in other words, not on a prototype). Unlike the internal `has` -// function, this public version can also traverse nested properties. -function has(obj, path) { - path = toPath(path); - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (!has$1(obj, key)) return false; - obj = obj[key]; - } - return !!length; -} - -// Keep the identity function around for default iteratees. -function identity(value) { - return value; -} - -// Returns a predicate for checking whether an object has a given set of -// `key:value` pairs. -function matcher(attrs) { - attrs = extendOwn({}, attrs); - return function(obj) { - return isMatch(obj, attrs); - }; -} - -// Creates a function that, when passed an object, will traverse that object’s -// properties down the given `path`, specified as an array of keys or indices. -function property(path) { - path = toPath(path); - return function(obj) { - return deepGet(obj, path); - }; -} - -// Internal function that returns an efficient (for current engines) version -// of the passed-in callback, to be repeatedly applied in other Underscore -// functions. -function optimizeCb(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; -} - -// An internal function to generate callbacks that can be applied to each -// element in a collection, returning the desired result — either `_.identity`, -// an arbitrary callback, a property matcher, or a property accessor. -function baseIteratee(value, context, argCount) { - if (value == null) return identity; - if (isFunction$1(value)) return optimizeCb(value, context, argCount); - if (isObject(value) && !isArray(value)) return matcher(value); - return property(value); -} - -// External wrapper for our callback generator. Users may customize -// `_.iteratee` if they want additional predicate/iteratee shorthand styles. -// This abstraction hides the internal-only `argCount` argument. -function iteratee(value, context) { - return baseIteratee(value, context, Infinity); -} -_$1.iteratee = iteratee; - -// The function we call internally to generate a callback. It invokes -// `_.iteratee` if overridden, otherwise `baseIteratee`. -function cb(value, context, argCount) { - if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); - return baseIteratee(value, context, argCount); -} - -// Returns the results of applying the `iteratee` to each element of `obj`. -// In contrast to `_.map` it returns an object. -function mapObject(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = keys(obj), - length = _keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = _keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Predicate-generating function. Often useful outside of Underscore. -function noop(){} - -// Generates a function for a given object that returns a given property. -function propertyOf(obj) { - if (obj == null) return noop; - return function(path) { - return get(obj, path); - }; -} - -// Run a function **n** times. -function times(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; -} - -// Return a random integer between `min` and `max` (inclusive). -function random(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); -} - -// A (possibly faster) way to get the current timestamp as an integer. -var now = Date.now || function() { - return new Date().getTime(); -}; - -// Internal helper to generate functions for escaping and unescaping strings -// to/from HTML interpolation. -function createEscaper(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; -} - -// Internal list of HTML entities for escaping. -var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' -}; - -// Function for escaping strings to HTML interpolation. -var _escape = createEscaper(escapeMap); - -// Internal list of HTML entities for unescaping. -var unescapeMap = invert(escapeMap); - -// Function for unescaping strings from HTML interpolation. -var _unescape = createEscaper(unescapeMap); - -// By default, Underscore uses ERB-style template delimiters. Change the -// following template settings to use alternative delimiters. -var templateSettings = _$1.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g -}; - -// When customizing `_.templateSettings`, if you don't want to define an -// interpolation, evaluation or escaping regex, we need one that is -// guaranteed not to match. -var noMatch = /(.)^/; - -// Certain characters need to be escaped so that they can be put into a -// string literal. -var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' -}; - -var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - -function escapeChar(match) { - return '\\' + escapes[match]; -} - -// In order to prevent third-party code injection through -// `_.templateSettings.variable`, we test it against the following regular -// expression. It is intentionally a bit more liberal than just matching valid -// identifiers, but still prevents possible loopholes through defaults or -// destructuring assignment. -var bareIdentifier = /^\s*(\w|\$)+\s*$/; - -// JavaScript micro-templating, similar to John Resig's implementation. -// Underscore templating handles arbitrary delimiters, preserves whitespace, -// and correctly escapes quotes within interpolated code. -// NB: `oldSettings` only exists for backwards compatibility. -function template(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = defaults({}, settings, _$1.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - var argument = settings.variable; - if (argument) { - // Insure against third-party code injection. (CVE-2021-23358) - if (!bareIdentifier.test(argument)) throw new Error( - 'variable is not a bare identifier: ' + argument - ); - } else { - // If a variable is not specified, place data values in local scope. - source = 'with(obj||{}){\n' + source + '}\n'; - argument = 'obj'; - } - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(argument, '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _$1); - }; - - // Provide the compiled source as a convenience for precompilation. - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; -} - -// Traverses the children of `obj` along `path`. If a child is a function, it -// is invoked with its parent as context. Returns the value of the final -// child, or `fallback` if any child is undefined. -function result(obj, path, fallback) { - path = toPath(path); - var length = path.length; - if (!length) { - return isFunction$1(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); } - obj = isFunction$1(prop) ? prop.call(obj) : prop; - } - return obj; -} - -// Generate a unique integer id (unique within the entire client session). -// Useful for temporary DOM ids. -var idCounter = 0; -function uniqueId(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; -} - -// Start chaining a wrapped Underscore object. -function chain(obj) { - var instance = _$1(obj); - instance._chain = true; - return instance; -} - -// Internal function to execute `sourceFunc` bound to `context` with optional -// `args`. Determines whether to execute a function as a constructor or as a -// normal function. -function executeBound(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (isObject(result)) return result; - return self; -} - -// Partially apply a function by creating a version that has had some of its -// arguments pre-filled, without changing its dynamic `this` context. `_` acts -// as a placeholder by default, allowing any combination of arguments to be -// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. -var partial = restArguments(function(func, boundArgs) { - var placeholder = partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; -}); - -partial.placeholder = _$1; - -// Create a function bound to a given object (assigning `this`, and arguments, -// optionally). -var bind = restArguments(function(func, context, args) { - if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; -}); - -// Internal helper for collection methods to determine whether a collection -// should be iterated as an array or as an object. -// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength -// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 -var isArrayLike = createSizePropertyCheck(getLength); - -// Internal implementation of a recursive `flatten` function. -function flatten$1(input, depth, strict, output) { - output = output || []; - if (!depth && depth !== 0) { - depth = Infinity; - } else if (depth <= 0) { - return output.concat(input); - } - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { - // Flatten current level of array or arguments object. - if (depth > 1) { - flatten$1(value, depth - 1, strict, output); - idx = output.length; - } else { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); } - } - return output; -} - -// Bind a number of an object's methods to that object. Remaining arguments -// are the method names to be bound. Useful for ensuring that all callbacks -// defined on an object belong to it. -var bindAll = restArguments(function(obj, keys) { - keys = flatten$1(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = bind(obj[key], obj); - } - return obj; -}); - -// Memoize an expensive function by storing its results. -function memoize(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; -} - -// Delays a function for the given number of milliseconds, and then calls -// it with the arguments supplied. -var delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); -}); - -// Defers a function, scheduling it to run after the current call stack has -// cleared. -var defer = partial(delay, _$1, 1); - -// Returns a function, that, when invoked, will only be triggered at most once -// during a given window of time. Normally, the throttled function will run -// as much as it can, without ever going more than once per `wait` duration; -// but if you'd like to disable the execution on the leading edge, pass -// `{leading: false}`. To disable execution on the trailing edge, ditto. -function throttle(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var _now = now(); - if (!previous && options.leading === false) previous = _now; - var remaining = wait - (_now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = _now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; -} - -// When a sequence of calls of the returned function ends, the argument -// function is triggered. The end of a sequence is defined by the `wait` -// parameter. If `immediate` is passed, the argument function will be -// triggered at the beginning of the sequence instead of at the end. -function debounce(func, wait, immediate) { - var timeout, previous, args, result, context; - - var later = function() { - var passed = now() - previous; - if (wait > passed) { - timeout = setTimeout(later, wait - passed); - } else { - timeout = null; - if (!immediate) result = func.apply(context, args); - // This check is needed because `func` can recursively invoke `debounced`. - if (!timeout) args = context = null; + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - }; - - var debounced = restArguments(function(_args) { - context = this; - args = _args; - previous = now(); - if (!timeout) { - timeout = setTimeout(later, wait); - if (immediate) result = func.apply(context, args); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = args = context = null; - }; - - return debounced; -} - -// Returns the first function passed as an argument to the second, -// allowing you to adjust arguments, run code before and after, and -// conditionally execute the original function. -function wrap(func, wrapper) { - return partial(wrapper, func); -} - -// Returns a negated version of the passed-in predicate. -function negate(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} - -// Returns a function that is the composition of a list of functions, each -// consuming the return value of the function that follows. -function compose() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; -} - -// Returns a function that will only be executed on and after the Nth call. -function after(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - }; -} - -// Returns a function that will only be executed up to (but not including) the -// Nth call. -function before(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (times <= 1) func = null; - return memo; - }; -} - -// Returns a function that will be executed at most one time, no matter how -// often you call it. Useful for lazy initialization. -var once = partial(before, 2); - -// Returns the first key on an object that passes a truth test. -function findKey(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = keys(obj), key; - for (var i = 0, length = _keys.length; i < length; i++) { - key = _keys[i]; - if (predicate(obj[key], key, obj)) return key; - } -} - -// Internal function to generate `_.findIndex` and `_.findLastIndex`. -function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); } - return -1; - }; -} - -// Returns the first index on an array-like that passes a truth test. -var findIndex = createPredicateIndexFinder(1); - -// Returns the last index on an array-like that passes a truth test. -var findLastIndex = createPredicateIndexFinder(-1); - -// Use a comparator function to figure out the smallest index at which -// an object should be inserted so as to maintain order. Uses binary search. -function sortedIndex(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; -} - -// Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. -function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), isNaN$1); - return idx >= 0 ? idx + i : -1; + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - return -1; - }; } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -// Return the position of the first occurrence of an item in an array, -// or -1 if the item is not included in the array. -// If the array is large and already in sort order, pass `true` -// for **isSorted** to use binary search. -var indexOf = createIndexFinder(1, findIndex, sortedIndex); - -// Return the position of the last occurrence of an item in an array, -// or -1 if the item is not included in the array. -var lastIndexOf = createIndexFinder(-1, findLastIndex); - -// Return the first value which passes a truth test. -function find(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? findIndex : findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; -} -// Convenience version of a common use case of `_.find`: getting the first -// object containing specific `key:value` pairs. -function findWhere(obj, attrs) { - return find(obj, matcher(attrs)); -} +/***/ }), -// The cornerstone for collection functions, an `each` -// implementation, aka `forEach`. -// Handles raw objects in addition to array-likes. Treats all -// sparse array-likes as if they were dense. -function each(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var _keys = keys(obj); - for (i = 0, length = _keys.length; i < length; i++) { - iteratee(obj[_keys[i]], _keys[i], obj); - } - } - return obj; -} +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { -// Return the results of applying the iteratee to each element. -function map(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Internal helper to create a reducing function, iterating left or right. -function createReduce(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[_keys ? _keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = _keys ? _keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; +"use strict"; - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -// **Reduce** builds up a single result from a list of values, aka `inject`, -// or `foldl`. -var reduce = createReduce(1); -// The right-associative version of reduce, also known as `foldr`. -var reduceRight = createReduce(-1); - -// Return all the elements that pass a truth test. -function filter(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; -} +/***/ }), -// Return all the elements for which a truth test fails. -function reject(obj, predicate, context) { - return filter(obj, negate(cb(predicate)), context); -} +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { -// Determine whether all of the elements pass a truth test. -function every(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; -} +"use strict"; -// Determine if at least one element in the object passes a truth test. -function some(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; -// Determine if the array or object contains a given item (using `===`). -function contains(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return indexOf(obj, item, fromIndex) >= 0; -} -// Invoke a method (with arguments) on every item in a collection. -var invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (isFunction$1(path)) { - func = path; - } else { - path = toPath(path); - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); -}); +/***/ }), -// Convenience version of a common use case of `_.map`: fetching a property. -function pluck(obj, key) { - return map(obj, property(key)); -} +/***/ 2877: +/***/ ((module) => { -// Convenience version of a common use case of `_.filter`: selecting only -// objects containing specific `key:value` pairs. -function where(obj, attrs) { - return filter(obj, matcher(attrs)); -} +module.exports = eval("require")("encoding"); -// Return the maximum element (or element-based computation). -function max(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} -// Return the minimum element (or element-based computation). -function min(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || (computed === Infinity && result === Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} +/***/ }), -// Safely create a real, live array from anything iterable. -var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; -function toArray(obj) { - if (!obj) return []; - if (isArray(obj)) return slice.call(obj); - if (isString(obj)) { - // Keep surrogate pair characters together. - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return map(obj, identity); - return values(obj); -} +/***/ 9491: +/***/ ((module) => { -// Sample **n** random values from a collection using the modern version of the -// [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). -// If **n** is not specified, returns a single random element. -// The internal `guard` argument allows it to work with `_.map`. -function sample(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = values(obj); - return obj[random(obj.length - 1)]; - } - var sample = toArray(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); -} +"use strict"; +module.exports = require("assert"); -// Shuffle a collection. -function shuffle(obj) { - return sample(obj, Infinity); -} +/***/ }), -// Sort the object's values by a criterion produced by an iteratee. -function sortBy(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return pluck(map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); -} - -// An internal function used for aggregate "group by" operations. -function group(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; -} +/***/ 6113: +/***/ ((module) => { -// Groups the object's values by a criterion. Pass either a string attribute -// to group by, or a function that returns the criterion. -var groupBy = group(function(result, value, key) { - if (has$1(result, key)) result[key].push(value); else result[key] = [value]; -}); +"use strict"; +module.exports = require("crypto"); -// Indexes the object's values by a criterion, similar to `_.groupBy`, but for -// when you know that your index values will be unique. -var indexBy = group(function(result, value, key) { - result[key] = value; -}); +/***/ }), -// Counts instances of an object that group by a certain criterion. Pass -// either a string attribute to count by, or a function that returns the -// criterion. -var countBy = group(function(result, value, key) { - if (has$1(result, key)) result[key]++; else result[key] = 1; -}); +/***/ 2361: +/***/ ((module) => { -// Split a collection into two arrays: one whose elements all pass the given -// truth test, and one whose elements all do not pass the truth test. -var partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); -}, true); +"use strict"; +module.exports = require("events"); -// Return the number of elements in a collection. -function size(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : keys(obj).length; -} +/***/ }), -// Internal `_.pick` helper function to determine whether `key` is an enumerable -// property name of `obj`. -function keyInObj(value, key, obj) { - return key in obj; -} +/***/ 7147: +/***/ ((module) => { -// Return a copy of the object only containing the allowed properties. -var pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (isFunction$1(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten$1(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; -}); +"use strict"; +module.exports = require("fs"); -// Return a copy of the object without the disallowed properties. -var omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (isFunction$1(iteratee)) { - iteratee = negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = map(flatten$1(keys, false, false), String); - iteratee = function(value, key) { - return !contains(keys, key); - }; - } - return pick(obj, iteratee, context); -}); +/***/ }), -// Returns everything but the last entry of the array. Especially useful on -// the arguments object. Passing **n** will return all the values in -// the array, excluding the last N. -function initial(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); -} +/***/ 3685: +/***/ ((module) => { -// Get the first element of an array. Passing **n** will return the first N -// values in the array. The **guard** check allows it to work with `_.map`. -function first(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[0]; - return initial(array, array.length - n); -} +"use strict"; +module.exports = require("http"); -// Returns everything but the first entry of the `array`. Especially useful on -// the `arguments` object. Passing an **n** will return the rest N values in the -// `array`. -function rest(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); -} +/***/ }), -// Get the last element of an array. Passing **n** will return the last N -// values in the array. -function last(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return rest(array, Math.max(0, array.length - n)); -} +/***/ 5687: +/***/ ((module) => { -// Trim out all falsy values from an array. -function compact(array) { - return filter(array, Boolean); -} +"use strict"; +module.exports = require("https"); -// Flatten out an array, either recursively (by default), or up to `depth`. -// Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. -function flatten(array, depth) { - return flatten$1(array, depth, false); -} +/***/ }), -// Take the difference between one array and a number of other arrays. -// Only the elements present in just the first array will remain. -var difference = restArguments(function(array, rest) { - rest = flatten$1(rest, true, true); - return filter(array, function(value){ - return !contains(rest, value); - }); -}); +/***/ 1808: +/***/ ((module) => { -// Return a version of the array that does not contain the specified value(s). -var without = restArguments(function(array, otherArrays) { - return difference(array, otherArrays); -}); +"use strict"; +module.exports = require("net"); -// Produce a duplicate-free version of the array. If the array has already -// been sorted, you have the option of using a faster algorithm. -// The faster algorithm will not work with an iteratee if the iteratee -// is not a one-to-one function, so providing an iteratee will disable -// the faster algorithm. -function uniq(array, isSorted, iteratee, context) { - if (!isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!contains(result, value)) { - result.push(value); - } - } - return result; -} +/***/ }), -// Produce an array that contains the union: each distinct element from all of -// the passed-in arrays. -var union = restArguments(function(arrays) { - return uniq(flatten$1(arrays, true, true)); -}); +/***/ 2037: +/***/ ((module) => { -// Produce an array that contains every item shared between all the -// passed-in arrays. -function intersection(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; -} +"use strict"; +module.exports = require("os"); -// Complement of zip. Unzip accepts an array of arrays and groups -// each array's elements on shared indices. -function unzip(array) { - var length = (array && max(array, getLength).length) || 0; - var result = Array(length); +/***/ }), - for (var index = 0; index < length; index++) { - result[index] = pluck(array, index); - } - return result; -} +/***/ 1017: +/***/ ((module) => { -// Zip together multiple lists into a single array -- elements that share -// an index go together. -var zip = restArguments(unzip); +"use strict"; +module.exports = require("path"); -// Converts lists into objects. Pass either a single array of `[key, value]` -// pairs, or two parallel arrays of the same length -- one of keys, and one of -// the corresponding values. Passing by pairs is the reverse of `_.pairs`. -function object(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; -} +/***/ }), -// Generate an integer Array containing an arithmetic progression. A port of -// the native Python `range()` function. See -// [the Python documentation](https://docs.python.org/library/functions.html#range). -function range(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } +/***/ 5477: +/***/ ((module) => { - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); +"use strict"; +module.exports = require("punycode"); - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } +/***/ }), - return range; -} +/***/ 2781: +/***/ ((module) => { -// Chunk a single array into multiple arrays, each containing `count` or fewer -// items. -function chunk(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; -} +"use strict"; +module.exports = require("stream"); -// Helper function to continue chaining intermediate results. -function chainResult(instance, obj) { - return instance._chain ? _$1(obj).chain() : obj; -} +/***/ }), -// Add your own custom functions to the Underscore object. -function mixin(obj) { - each(functions(obj), function(name) { - var func = _$1[name] = obj[name]; - _$1.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_$1, args)); - }; - }); - return _$1; -} - -// Add all mutator `Array` functions to the wrapper. -each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) { - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) { - delete obj[0]; - } - } - return chainResult(this, obj); - }; -}); +/***/ 4404: +/***/ ((module) => { -// Add all accessor `Array` functions to the wrapper. -each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) obj = method.apply(obj, arguments); - return chainResult(this, obj); - }; -}); +"use strict"; +module.exports = require("tls"); -// Named Exports - -var allExports = { - __proto__: null, - VERSION: VERSION, - restArguments: restArguments, - isObject: isObject, - isNull: isNull, - isUndefined: isUndefined, - isBoolean: isBoolean, - isElement: isElement, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isRegExp: isRegExp, - isError: isError, - isSymbol: isSymbol, - isArrayBuffer: isArrayBuffer, - isDataView: isDataView$1, - isArray: isArray, - isFunction: isFunction$1, - isArguments: isArguments$1, - isFinite: isFinite$1, - isNaN: isNaN$1, - isTypedArray: isTypedArray$1, - isEmpty: isEmpty, - isMatch: isMatch, - isEqual: isEqual, - isMap: isMap, - isWeakMap: isWeakMap, - isSet: isSet, - isWeakSet: isWeakSet, - keys: keys, - allKeys: allKeys, - values: values, - pairs: pairs, - invert: invert, - functions: functions, - methods: functions, - extend: extend, - extendOwn: extendOwn, - assign: extendOwn, - defaults: defaults, - create: create, - clone: clone, - tap: tap, - get: get, - has: has, - mapObject: mapObject, - identity: identity, - constant: constant, - noop: noop, - toPath: toPath$1, - property: property, - propertyOf: propertyOf, - matcher: matcher, - matches: matcher, - times: times, - random: random, - now: now, - escape: _escape, - unescape: _unescape, - templateSettings: templateSettings, - template: template, - result: result, - uniqueId: uniqueId, - chain: chain, - iteratee: iteratee, - partial: partial, - bind: bind, - bindAll: bindAll, - memoize: memoize, - delay: delay, - defer: defer, - throttle: throttle, - debounce: debounce, - wrap: wrap, - negate: negate, - compose: compose, - after: after, - before: before, - once: once, - findKey: findKey, - findIndex: findIndex, - findLastIndex: findLastIndex, - sortedIndex: sortedIndex, - indexOf: indexOf, - lastIndexOf: lastIndexOf, - find: find, - detect: find, - findWhere: findWhere, - each: each, - forEach: each, - map: map, - collect: map, - reduce: reduce, - foldl: reduce, - inject: reduce, - reduceRight: reduceRight, - foldr: reduceRight, - filter: filter, - select: filter, - reject: reject, - every: every, - all: every, - some: some, - any: some, - contains: contains, - includes: contains, - include: contains, - invoke: invoke, - pluck: pluck, - where: where, - max: max, - min: min, - shuffle: shuffle, - sample: sample, - sortBy: sortBy, - groupBy: groupBy, - indexBy: indexBy, - countBy: countBy, - partition: partition, - toArray: toArray, - size: size, - pick: pick, - omit: omit, - first: first, - head: first, - take: first, - initial: initial, - last: last, - rest: rest, - tail: rest, - drop: rest, - compact: compact, - flatten: flatten, - without: without, - uniq: uniq, - unique: uniq, - union: union, - intersection: intersection, - difference: difference, - unzip: unzip, - transpose: unzip, - zip: zip, - object: object, - range: range, - chunk: chunk, - mixin: mixin, - 'default': _$1 -}; +/***/ }), -// Default Export - -// Add all of the Underscore functions to the wrapper object. -var _ = mixin(allExports); -// Legacy Node.js API. -_._ = _; - -exports.VERSION = VERSION; -exports._ = _; -exports._escape = _escape; -exports._unescape = _unescape; -exports.after = after; -exports.allKeys = allKeys; -exports.before = before; -exports.bind = bind; -exports.bindAll = bindAll; -exports.chain = chain; -exports.chunk = chunk; -exports.clone = clone; -exports.compact = compact; -exports.compose = compose; -exports.constant = constant; -exports.contains = contains; -exports.countBy = countBy; -exports.create = create; -exports.debounce = debounce; -exports.defaults = defaults; -exports.defer = defer; -exports.delay = delay; -exports.difference = difference; -exports.each = each; -exports.every = every; -exports.extend = extend; -exports.extendOwn = extendOwn; -exports.filter = filter; -exports.find = find; -exports.findIndex = findIndex; -exports.findKey = findKey; -exports.findLastIndex = findLastIndex; -exports.findWhere = findWhere; -exports.first = first; -exports.flatten = flatten; -exports.functions = functions; -exports.get = get; -exports.groupBy = groupBy; -exports.has = has; -exports.identity = identity; -exports.indexBy = indexBy; -exports.indexOf = indexOf; -exports.initial = initial; -exports.intersection = intersection; -exports.invert = invert; -exports.invoke = invoke; -exports.isArguments = isArguments$1; -exports.isArray = isArray; -exports.isArrayBuffer = isArrayBuffer; -exports.isBoolean = isBoolean; -exports.isDataView = isDataView$1; -exports.isDate = isDate; -exports.isElement = isElement; -exports.isEmpty = isEmpty; -exports.isEqual = isEqual; -exports.isError = isError; -exports.isFinite = isFinite$1; -exports.isFunction = isFunction$1; -exports.isMap = isMap; -exports.isMatch = isMatch; -exports.isNaN = isNaN$1; -exports.isNull = isNull; -exports.isNumber = isNumber; -exports.isObject = isObject; -exports.isRegExp = isRegExp; -exports.isSet = isSet; -exports.isString = isString; -exports.isSymbol = isSymbol; -exports.isTypedArray = isTypedArray$1; -exports.isUndefined = isUndefined; -exports.isWeakMap = isWeakMap; -exports.isWeakSet = isWeakSet; -exports.iteratee = iteratee; -exports.keys = keys; -exports.last = last; -exports.lastIndexOf = lastIndexOf; -exports.map = map; -exports.mapObject = mapObject; -exports.matcher = matcher; -exports.max = max; -exports.memoize = memoize; -exports.min = min; -exports.mixin = mixin; -exports.negate = negate; -exports.noop = noop; -exports.now = now; -exports.object = object; -exports.omit = omit; -exports.once = once; -exports.pairs = pairs; -exports.partial = partial; -exports.partition = partition; -exports.pick = pick; -exports.pluck = pluck; -exports.property = property; -exports.propertyOf = propertyOf; -exports.random = random; -exports.range = range; -exports.reduce = reduce; -exports.reduceRight = reduceRight; -exports.reject = reject; -exports.rest = rest; -exports.restArguments = restArguments; -exports.result = result; -exports.sample = sample; -exports.shuffle = shuffle; -exports.size = size; -exports.some = some; -exports.sortBy = sortBy; -exports.sortedIndex = sortedIndex; -exports.tap = tap; -exports.template = template; -exports.templateSettings = templateSettings; -exports.throttle = throttle; -exports.times = times; -exports.toArray = toArray; -exports.toPath = toPath$1; -exports.union = union; -exports.uniq = uniq; -exports.uniqueId = uniqueId; -exports.unzip = unzip; -exports.values = values; -exports.where = where; -exports.without = without; -exports.wrap = wrap; -exports.zip = zip; -//# sourceMappingURL=underscore-node-f.cjs.map +/***/ 7310: +/***/ ((module) => { +"use strict"; +module.exports = require("url"); /***/ }), -/***/ 5067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -var underscoreNodeF = __nccwpck_require__(6717); +/***/ 3837: +/***/ ((module) => { +"use strict"; +module.exports = require("util"); +/***/ }), -module.exports = underscoreNodeF._; -//# sourceMappingURL=underscore-node.cjs.map +/***/ 9796: +/***/ ((module) => { +"use strict"; +module.exports = require("zlib"); /***/ }), @@ -15963,7 +12110,7 @@ var __webpack_exports__ = {}; (() => { const core = __nccwpck_require__(2186); const CONST = __nccwpck_require__(4097); -const GithubUtils = __nccwpck_require__(7999); +const GithubUtils = __nccwpck_require__(9296); const issueNumber = core.getInput('ISSUE_NUMBER', {required: true}); const comment = core.getInput('COMMENT', {required: true}); diff --git a/.github/actions/javascript/reviewerChecklist/index.js b/.github/actions/javascript/reviewerChecklist/index.js index 322b529b89bf..b63c55ae5eb8 100644 --- a/.github/actions/javascript/reviewerChecklist/index.js +++ b/.github/actions/javascript/reviewerChecklist/index.js @@ -28,784 +28,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4841,3898 +4295,2288 @@ const Endpoints = { updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], - updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], - updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], - updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], - updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { - renamed: ["repos", "updateStatusCheckProtection"] - }], - updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], - updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], - updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], - uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { - baseUrl: "https://uploads.github.com" - }] - }, - search: { - code: ["GET /search/code"], - commits: ["GET /search/commits"], - issuesAndPullRequests: ["GET /search/issues"], - labels: ["GET /search/labels"], - repos: ["GET /search/repositories"], - topics: ["GET /search/topics"], - users: ["GET /search/users"] - }, - secretScanning: { - getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; - - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; - - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; - - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; - - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; - - return Bottleneck; - - }).call(commonjsGlobal); - - var Bottleneck_1 = Bottleneck; - - var lib = Bottleneck_1; - - return lib; - -}))); - - -/***/ }), + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +const VERSION = "5.16.2"; -"use strict"; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!newMethods[scope]) { + newMethods[scope] = {}; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + const scopeMethods = newMethods[scope]; - /* istanbul ignore next */ + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); } - - this.name = 'Deprecation'; } + return newMethods; } -exports.Deprecation = Deprecation; - - -/***/ }), +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` -"use strict"; + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -function isPlainObject(o) { - var ctor,prot; + if (!(alias in options)) { + options[alias] = options[name]; + } - if (isObject(o) === false) return false; + delete options[name]; + } + } - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + return requestWithDefaults(...args); } - // Most likely a plain Object - return true; + return Object.assign(withDecorations, requestWithDefaults); } -exports.isPlainObject = isPlainObject; - - -/***/ }), - -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; } +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); +"use strict"; -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +Object.defineProperty(exports, "__esModule", ({ value: true })); -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -module.exports = ListCache; +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); +const VERSION = "4.1.0"; -/***/ }), +const noop = () => Promise.resolve(); // @ts-expect-error -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; -module.exports = Map; + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -/***/ }), + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; + const req = state.global.key(state.id).schedule(jobOptions, request, options); -/***/ }), + if (isGraphQL) { + const res = await req; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -var root = __nccwpck_require__(9882); + return req; +} -/** Built-in value references. */ -var Symbol = root.Symbol; +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; -module.exports = Symbol; +function routeMatcher(paths) { + // EXAMPLE. For the following paths: + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: -/***/ }), + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -/***/ 4356: -/***/ ((module) => { + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + return new RegExp(regex, "i"); } -module.exports = arrayMap; - +// @ts-expect-error -/***/ }), +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -var eq = __nccwpck_require__(1901); +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } + if (!enabled) { + return {}; } - return -1; -} - -module.exports = assocIndexOf; + const common = { + connection, + timeout + }; -/***/ }), + if (groups.global == null) { + createGroups(Bottleneck, common); + } -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); + } - var index = 0, - length = path.length; + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; -} + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error -module.exports = baseGet; + events.on("rate-limit", state.onRateLimit); // @ts-expect-error + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error -/***/ }), + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + return {}; + }(); -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; + } + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = baseGetTag; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 411: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseIsNative; - - -/***/ }), - -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +function HookCollection () { + var state = { + registry: {} + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; + return hook +} -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + return HookCollection() } -module.exports = baseToString; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() + +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 5549: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = addHook; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; + } -var root = __nccwpck_require__(9882); + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; + } -module.exports = coreJsData; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2085: +/***/ 4670: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; +module.exports = register; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); + } -/***/ }), + if (!options) { + options = {}; + } -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -var isKeyable = __nccwpck_require__(3308); + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); } -module.exports = getMapData; - /***/ }), -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); +/***/ 6819: +/***/ ((module) => { -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} +module.exports = removeHook; -module.exports = getNative; +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -/***/ }), + if (index === -1) { + return; + } -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + state.registry[name].splice(index, 1); +} -var Symbol = __nccwpck_require__(9213); -/** Used for built-in method references. */ -var objectProto = Object.prototype; +/***/ }), -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; -module.exports = getRawTag; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; + var parser = { + load: load, + overwrite: overwrite + }; -/***/ }), + var DLList; -/***/ 3542: -/***/ ((module) => { + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } -module.exports = getValue; + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ }), + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -var nativeCreate = __nccwpck_require__(3041); + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + }; -module.exports = hashClear; + var DLList_1 = DLList; + var Events; -/***/ }), + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/***/ 712: -/***/ ((module) => { + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } -module.exports = hashDelete; + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } + }; -/***/ }), + var Events_1 = Events; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var DLList$1, Events$1, Queues; -var nativeCreate = __nccwpck_require__(3041); + DLList$1 = DLList_1; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + Events$1 = Events_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } -module.exports = hashGet; + push(job) { + return this._lists[job.options.priority].push(job); + } + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ }), + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -var nativeCreate = __nccwpck_require__(3041); + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + }; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var Queues_1 = Queues; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var BottleneckError; -module.exports = hashHas; + BottleneckError = class BottleneckError extends Error {}; + var BottleneckError_1 = BottleneckError; -/***/ }), + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + NUM_PRIORITIES = 10; -var nativeCreate = __nccwpck_require__(3041); + DEFAULT_PRIORITY = 5; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + parser$1 = parser; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + BottleneckError$1 = BottleneckError_1; -module.exports = hashSet; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ }), + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } -module.exports = isKey; + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ }), + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/***/ 3308: -/***/ ((module) => { + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } -module.exports = isKeyable; + }; + var Job_1 = Job; -/***/ }), + var BottleneckError$2, LocalDatastore, parser$2; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + parser$2 = parser; -var coreJsData = __nccwpck_require__(8380); + BottleneckError$2 = BottleneckError_1; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } -module.exports = isMasked; + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ }), + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/***/ 9792: -/***/ ((module) => { + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } -module.exports = listCacheClear; + async __running__() { + await this.yieldLoop(); + return this._running; + } + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ }), + async __done__() { + await this.yieldLoop(); + return this._done; + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -var assocIndexOf = __nccwpck_require__(6752); + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** Built-in value references. */ -var splice = arrayProto.splice; + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + isBlocked(now) { + return this._unblockTime >= now; + } -module.exports = listCacheDelete; + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ }), + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -var assocIndexOf = __nccwpck_require__(6752); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } - return index < 0 ? undefined : data[index][1]; -} + }; -module.exports = listCacheGet; + var LocalDatastore_1 = LocalDatastore; + var BottleneckError$3, States; -/***/ }), + BottleneckError$3 = BottleneckError_1; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -var assocIndexOf = __nccwpck_require__(6752); + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } -module.exports = listCacheHas; + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ }), + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -var assocIndexOf = __nccwpck_require__(6752); + }; -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + var States_1 = States; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var DLList$2, Sync; -module.exports = listCacheSet; + DLList$2 = DLList_1; + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ }), + isEmpty() { + return this._queue.length === 0; + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + }; -module.exports = mapCacheClear; + var Sync_1 = Sync; + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ }), + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getMapData = __nccwpck_require__(9980); + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; + parser$3 = parser; -/***/ }), + Events$2 = Events_1; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + RedisConnection$1 = require$$2; -var getMapData = __nccwpck_require__(9980); + IORedisConnection$1 = require$$3; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + Scripts$1 = require$$4; -module.exports = mapCacheGet; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ }), + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -var getMapData = __nccwpck_require__(9980); + keys() { + return Object.keys(this.instances); + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13572,2387 +11416,690 @@ function validate(uuid) { return typeof uuid === 'string' && _regex.default.test(uuid); } -var _default = validate; -exports["default"] = _default; - -/***/ }), - -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} - - -/***/ }), - -/***/ 2877: -/***/ ((module) => { - -module.exports = eval("require")("encoding"); - - -/***/ }), - -/***/ 9491: -/***/ ((module) => { - -"use strict"; -module.exports = require("assert"); - -/***/ }), - -/***/ 6113: -/***/ ((module) => { - -"use strict"; -module.exports = require("crypto"); - -/***/ }), - -/***/ 2361: -/***/ ((module) => { - -"use strict"; -module.exports = require("events"); - -/***/ }), - -/***/ 7147: -/***/ ((module) => { - -"use strict"; -module.exports = require("fs"); - -/***/ }), - -/***/ 3685: -/***/ ((module) => { - -"use strict"; -module.exports = require("http"); - -/***/ }), - -/***/ 5687: -/***/ ((module) => { - -"use strict"; -module.exports = require("https"); - -/***/ }), - -/***/ 1808: -/***/ ((module) => { - -"use strict"; -module.exports = require("net"); - -/***/ }), - -/***/ 2037: -/***/ ((module) => { - -"use strict"; -module.exports = require("os"); - -/***/ }), - -/***/ 1017: -/***/ ((module) => { - -"use strict"; -module.exports = require("path"); - -/***/ }), - -/***/ 5477: -/***/ ((module) => { - -"use strict"; -module.exports = require("punycode"); - -/***/ }), - -/***/ 2781: -/***/ ((module) => { - -"use strict"; -module.exports = require("stream"); - -/***/ }), - -/***/ 4404: -/***/ ((module) => { - -"use strict"; -module.exports = require("tls"); - -/***/ }), - -/***/ 7310: -/***/ ((module) => { - -"use strict"; -module.exports = require("url"); - -/***/ }), - -/***/ 3837: -/***/ ((module) => { - -"use strict"; -module.exports = require("util"); - -/***/ }), - -/***/ 9796: -/***/ ((module) => { - -"use strict"; -module.exports = require("zlib"); - -/***/ }), - -/***/ 6717: -/***/ ((__unused_webpack_module, exports) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -// Current version. -var VERSION = '1.13.6'; - -// Establish the root object, `window` (`self`) in the browser, `global` -// on the server, or `this` in some virtual machines. We use `self` -// instead of `window` for `WebWorker` support. -var root = (typeof self == 'object' && self.self === self && self) || - (typeof global == 'object' && global.global === global && global) || - Function('return this')() || - {}; - -// Save bytes in the minified (but not gzipped) version: -var ArrayProto = Array.prototype, ObjProto = Object.prototype; -var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; - -// Create quick reference variables for speed access to core prototypes. -var push = ArrayProto.push, - slice = ArrayProto.slice, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - -// Modern feature detection. -var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', - supportsDataView = typeof DataView !== 'undefined'; - -// All **ECMAScript 5+** native function implementations that we hope to use -// are declared here. -var nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeCreate = Object.create, - nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; - -// Create references to these builtin functions because we override them. -var _isNaN = isNaN, - _isFinite = isFinite; - -// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. -var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); -var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', - 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; - -// The largest integer that can be represented exactly. -var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; - -// Some functions take a variable number of arguments, or a few expected -// arguments at the beginning and then a variable number of values to operate -// on. This helper accumulates all remaining arguments past the function’s -// argument length (or an explicit `startIndex`), into an array that becomes -// the last argument. Similar to ES6’s "rest parameter". -function restArguments(func, startIndex) { - startIndex = startIndex == null ? func.length - 1 : +startIndex; - return function() { - var length = Math.max(arguments.length - startIndex, 0), - rest = Array(length), - index = 0; - for (; index < length; index++) { - rest[index] = arguments[index + startIndex]; - } - switch (startIndex) { - case 0: return func.call(this, rest); - case 1: return func.call(this, arguments[0], rest); - case 2: return func.call(this, arguments[0], arguments[1], rest); - } - var args = Array(startIndex + 1); - for (index = 0; index < startIndex; index++) { - args[index] = arguments[index]; - } - args[startIndex] = rest; - return func.apply(this, args); - }; -} - -// Is a given variable an object? -function isObject(obj) { - var type = typeof obj; - return type === 'function' || (type === 'object' && !!obj); -} - -// Is a given value equal to null? -function isNull(obj) { - return obj === null; -} - -// Is a given variable undefined? -function isUndefined(obj) { - return obj === void 0; -} - -// Is a given value a boolean? -function isBoolean(obj) { - return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; -} - -// Is a given value a DOM element? -function isElement(obj) { - return !!(obj && obj.nodeType === 1); -} - -// Internal function for creating a `toString`-based type tester. -function tagTester(name) { - var tag = '[object ' + name + ']'; - return function(obj) { - return toString.call(obj) === tag; - }; -} - -var isString = tagTester('String'); - -var isNumber = tagTester('Number'); - -var isDate = tagTester('Date'); - -var isRegExp = tagTester('RegExp'); - -var isError = tagTester('Error'); - -var isSymbol = tagTester('Symbol'); - -var isArrayBuffer = tagTester('ArrayBuffer'); - -var isFunction = tagTester('Function'); - -// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old -// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). -var nodelist = root.document && root.document.childNodes; -if ( true && typeof Int8Array != 'object' && typeof nodelist != 'function') { - isFunction = function(obj) { - return typeof obj == 'function' || false; - }; -} - -var isFunction$1 = isFunction; - -var hasObjectTag = tagTester('Object'); +var _default = validate; +exports["default"] = _default; -// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. -// In IE 11, the most common among them, this problem also applies to -// `Map`, `WeakMap` and `Set`. -var hasStringTagBug = ( - supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) - ), - isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); +/***/ }), -var isDataView = tagTester('DataView'); +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -// In IE 10 - Edge 13, we need a different heuristic -// to determine whether an object is a `DataView`. -function ie10IsDataView(obj) { - return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); -} +"use strict"; -var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); -// Is a given value an array? -// Delegates to ECMA5's native `Array.isArray`. -var isArray = nativeIsArray || tagTester('Array'); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -// Internal function to check whether `key` is an own property name of `obj`. -function has$1(obj, key) { - return obj != null && hasOwnProperty.call(obj, key); -} +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -var isArguments = tagTester('Arguments'); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// Define a fallback version of the method in browsers (ahem, IE < 9), where -// there isn't any inspectable "Arguments" type. -(function() { - if (!isArguments(arguments)) { - isArguments = function(obj) { - return has$1(obj, 'callee'); - }; +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); } -}()); - -var isArguments$1 = isArguments; - -// Is a given object a finite number? -function isFinite$1(obj) { - return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); -} - -// Is the given value `NaN`? -function isNaN$1(obj) { - return isNumber(obj) && _isNaN(obj); -} -// Predicate-generating function. Often useful outside of Underscore. -function constant(value) { - return function() { - return value; - }; + return parseInt(uuid.substr(14, 1), 16); } -// Common internal logic for `isArrayLike` and `isBufferLike`. -function createSizePropertyCheck(getSizeProperty) { - return function(collection) { - var sizeProperty = getSizeProperty(collection); - return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; - } -} +var _default = version; +exports["default"] = _default; -// Internal helper to generate a function to obtain property `key` from `obj`. -function shallowProperty(key) { - return function(obj) { - return obj == null ? void 0 : obj[key]; - }; -} +/***/ }), -// Internal helper to obtain the `byteLength` property of an object. -var getByteLength = shallowProperty('byteLength'); +/***/ 2940: +/***/ ((module) => { -// Internal helper to determine whether we should spend extensive checks against -// `ArrayBuffer` et al. -var isBufferLike = createSizePropertyCheck(getByteLength); +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) -// Is a given value a typed array? -var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; -function isTypedArray(obj) { - // `ArrayBuffer.isView` is the most future-proof, so use it when available. - // Otherwise, fall back on the above regular expression. - return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : - isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); -} + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) -// Internal helper to obtain the `length` property of an object. -var getLength = shallowProperty('length'); + return wrapper -// Internal helper to create a simple lookup structure. -// `collectNonEnumProps` used to depend on `_.contains`, but this led to -// circular imports. `emulatedSet` is a one-off solution that only works for -// arrays of strings. -function emulatedSet(keys) { - var hash = {}; - for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; - return { - contains: function(key) { return hash[key] === true; }, - push: function(key) { - hash[key] = true; - return keys.push(key); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] } - }; + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } } -// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't -// be iterated by `for key in ...` and thus missed. Extends `keys` in place if -// needed. -function collectNonEnumProps(obj, keys) { - keys = emulatedSet(keys); - var nonEnumIdx = nonEnumerableProps.length; - var constructor = obj.constructor; - var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto; - // Constructor is a special case. - var prop = 'constructor'; - if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; - while (nonEnumIdx--) { - prop = nonEnumerableProps[nonEnumIdx]; - if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { - keys.push(prop); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); } - } -} - -// Retrieve the names of an object's own properties. -// Delegates to **ECMAScript 5**'s native `Object.keys`. -function keys(obj) { - if (!isObject(obj)) return []; - if (nativeKeys) return nativeKeys(obj); - var keys = []; - for (var key in obj) if (has$1(obj, key)) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Is a given array, string, or object empty? -// An "empty" object has no enumerable own-properties. -function isEmpty(obj) { - if (obj == null) return true; - // Skip the more expensive `toString`-based type checks if `obj` has no - // `.length`. - var length = getLength(obj); - if (typeof length == 'number' && ( - isArray(obj) || isString(obj) || isArguments$1(obj) - )) return length === 0; - return getLength(keys(obj)) === 0; -} - -// Returns whether an object has a given set of `key:value` pairs. -function isMatch(object, attrs) { - var _keys = keys(attrs), length = _keys.length; - if (object == null) return !length; - var obj = Object(object); - for (var i = 0; i < length; i++) { - var key = _keys[i]; - if (attrs[key] !== obj[key] || !(key in obj)) return false; - } - return true; -} - -// If Underscore is called as a function, it returns a wrapped object that can -// be used OO-style. This wrapper holds altered versions of all functions added -// through `_.mixin`. Wrapped objects may be chained. -function _$1(obj) { - if (obj instanceof _$1) return obj; - if (!(this instanceof _$1)) return new _$1(obj); - this._wrapped = obj; -} - -_$1.VERSION = VERSION; - -// Extracts the result from a wrapped and chained object. -_$1.prototype.value = function() { - return this._wrapped; -}; - -// Provide unwrapping proxies for some methods used in engine operations -// such as arithmetic and JSON stringification. -_$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; - -_$1.prototype.toString = function() { - return String(this._wrapped); -}; - -// Internal function to wrap or shallow-copy an ArrayBuffer, -// typed array or DataView to a new view, reusing the buffer. -function toBufferView(bufferSource) { - return new Uint8Array( - bufferSource.buffer || bufferSource, - bufferSource.byteOffset || 0, - getByteLength(bufferSource) - ); -} - -// We use this string twice, so give it a name for minification. -var tagDataView = '[object DataView]'; - -// Internal recursive comparison function for `_.isEqual`. -function eq(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -// Internal recursive comparison function for `_.isEqual`. -function deepEq(a, b, aStack, bStack) { - // Unwrap any wrapped objects. - if (a instanceof _$1) a = a._wrapped; - if (b instanceof _$1) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - // Work around a bug in IE 10 - Edge 13. - if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { - if (!isDataView$1(b)) return false; - className = tagDataView; - } - switch (className) { - // These types are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - case '[object ArrayBuffer]': - case tagDataView: - // Coerce to typed array so we can fall through. - return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); - } - - var areArrays = className === '[object Array]'; - if (!areArrays && isTypedArray$1(a)) { - var byteLength = getByteLength(a); - if (byteLength !== getByteLength(b)) return false; - if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; - areArrays = true; - } - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && - isFunction$1(bCtor) && bCtor instanceof bCtor) - && ('constructor' in a && 'constructor' in b)) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!eq(a[length], b[length], aStack, bStack)) return false; + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); } - } else { - // Deep compare objects. - var _keys = keys(a), key; - length = _keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = _keys[length]; - if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -// Perform a deep comparison to check if two objects are equal. -function isEqual(a, b) { - return eq(a, b); -} - -// Retrieve all the enumerable property names of an object. -function allKeys(obj) { - if (!isObject(obj)) return []; - var keys = []; - for (var key in obj) keys.push(key); - // Ahem, IE < 9. - if (hasEnumBug) collectNonEnumProps(obj, keys); - return keys; -} - -// Since the regular `Object.prototype.toString` type tests don't work for -// some types in IE 11, we use a fingerprinting heuristic instead, based -// on the methods. It's not great, but it's the best we got. -// The fingerprint method lists are defined below. -function ie11fingerprint(methods) { - var length = getLength(methods); - return function(obj) { - if (obj == null) return false; - // `Map`, `WeakMap` and `Set` have no enumerable keys. - var keys = allKeys(obj); - if (getLength(keys)) return false; - for (var i = 0; i < length; i++) { - if (!isFunction$1(obj[methods[i]])) return false; - } - // If we are testing against `WeakMap`, we need to ensure that - // `obj` doesn't have a `forEach` method in order to distinguish - // it from a regular `Map`. - return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); - }; -} - -// In the interest of compact minification, we write -// each string in the fingerprints only once. -var forEachName = 'forEach', - hasName = 'has', - commonInit = ['clear', 'delete'], - mapTail = ['get', hasName, 'set']; - -// `Map`, `WeakMap` and `Set` each have slightly different -// combinations of the above sublists. -var mapMethods = commonInit.concat(forEachName, mapTail), - weakMapMethods = commonInit.concat(mapTail), - setMethods = ['add'].concat(commonInit, forEachName, hasName); - -var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); - -var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); - -var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); - -var isWeakSet = tagTester('WeakSet'); - -// Retrieve the values of an object's properties. -function values(obj) { - var _keys = keys(obj); - var length = _keys.length; - var values = Array(length); - for (var i = 0; i < length; i++) { - values[i] = obj[_keys[i]]; - } - return values; -} - -// Convert an object into a list of `[key, value]` pairs. -// The opposite of `_.object` with one argument. -function pairs(obj) { - var _keys = keys(obj); - var length = _keys.length; - var pairs = Array(length); - for (var i = 0; i < length; i++) { - pairs[i] = [_keys[i], obj[_keys[i]]]; - } - return pairs; -} - -// Invert the keys and values of an object. The values must be serializable. -function invert(obj) { - var result = {}; - var _keys = keys(obj); - for (var i = 0, length = _keys.length; i < length; i++) { - result[obj[_keys[i]]] = _keys[i]; - } - return result; -} - -// Return a sorted list of the function names available on the object. -function functions(obj) { - var names = []; - for (var key in obj) { - if (isFunction$1(obj[key])) names.push(key); - } - return names.sort(); -} - -// An internal function for creating assigner functions. -function createAssigner(keysFunc, defaults) { - return function(obj) { - var length = arguments.length; - if (defaults) obj = Object(obj); - if (length < 2 || obj == null) return obj; - for (var index = 1; index < length; index++) { - var source = arguments[index], - keys = keysFunc(source), - l = keys.length; - for (var i = 0; i < l; i++) { - var key = keys[i]; - if (!defaults || obj[key] === void 0) obj[key] = source[key]; - } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); } - return obj; - }; -} - -// Extend a given object with all the properties in passed-in object(s). -var extend = createAssigner(allKeys); - -// Assigns a given object with all the own properties in the passed-in -// object(s). -// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) -var extendOwn = createAssigner(keys); - -// Fill in a given object with default properties. -var defaults = createAssigner(allKeys, true); - -// Create a naked function reference for surrogate-prototype-swapping. -function ctor() { - return function(){}; -} - -// An internal function for creating a new object that inherits from another. -function baseCreate(prototype) { - if (!isObject(prototype)) return {}; - if (nativeCreate) return nativeCreate(prototype); - var Ctor = ctor(); - Ctor.prototype = prototype; - var result = new Ctor; - Ctor.prototype = null; - return result; -} - -// Creates an object that inherits from the given prototype object. -// If additional properties are provided then they will be added to the -// created object. -function create(prototype, props) { - var result = baseCreate(prototype); - if (props) extendOwn(result, props); - return result; -} - -// Create a (shallow-cloned) duplicate of an object. -function clone(obj) { - if (!isObject(obj)) return obj; - return isArray(obj) ? obj.slice() : extend({}, obj); -} - -// Invokes `interceptor` with the `obj` and then returns `obj`. -// The primary purpose of this method is to "tap into" a method chain, in -// order to perform operations on intermediate results within the chain. -function tap(obj, interceptor) { - interceptor(obj); - return obj; -} - -// Normalize a (deep) property `path` to array. -// Like `_.iteratee`, this function can be customized. -function toPath$1(path) { - return isArray(path) ? path : [path]; -} -_$1.toPath = toPath$1; - -// Internal wrapper for `_.toPath` to enable minification. -// Similar to `cb` for `_.iteratee`. -function toPath(path) { - return _$1.toPath(path); -} - -// Internal function to obtain a nested property in `obj` along `path`. -function deepGet(obj, path) { - var length = path.length; - for (var i = 0; i < length; i++) { - if (obj == null) return void 0; - obj = obj[path[i]]; - } - return length ? obj : void 0; -} - -// Get the value of the (deep) property on `path` from `object`. -// If any property in `path` does not exist or if the value is -// `undefined`, return `defaultValue` instead. -// The `path` is normalized through `_.toPath`. -function get(object, path, defaultValue) { - var value = deepGet(object, toPath(path)); - return isUndefined(value) ? defaultValue : value; -} - -// Shortcut function for checking if an object has a given property directly on -// itself (in other words, not on a prototype). Unlike the internal `has` -// function, this public version can also traverse nested properties. -function has(obj, path) { - path = toPath(path); - var length = path.length; - for (var i = 0; i < length; i++) { - var key = path[i]; - if (!has$1(obj, key)) return false; - obj = obj[key]; - } - return !!length; -} - -// Keep the identity function around for default iteratees. -function identity(value) { - return value; -} - -// Returns a predicate for checking whether an object has a given set of -// `key:value` pairs. -function matcher(attrs) { - attrs = extendOwn({}, attrs); - return function(obj) { - return isMatch(obj, attrs); - }; -} - -// Creates a function that, when passed an object, will traverse that object’s -// properties down the given `path`, specified as an array of keys or indices. -function property(path) { - path = toPath(path); - return function(obj) { - return deepGet(obj, path); - }; -} - -// Internal function that returns an efficient (for current engines) version -// of the passed-in callback, to be repeatedly applied in other Underscore -// functions. -function optimizeCb(func, context, argCount) { - if (context === void 0) return func; - switch (argCount == null ? 3 : argCount) { - case 1: return function(value) { - return func.call(context, value); - }; - // The 2-argument case is omitted because we’re not using it. - case 3: return function(value, index, collection) { - return func.call(context, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(context, accumulator, value, index, collection); - }; - } - return function() { - return func.apply(context, arguments); - }; -} - -// An internal function to generate callbacks that can be applied to each -// element in a collection, returning the desired result — either `_.identity`, -// an arbitrary callback, a property matcher, or a property accessor. -function baseIteratee(value, context, argCount) { - if (value == null) return identity; - if (isFunction$1(value)) return optimizeCb(value, context, argCount); - if (isObject(value) && !isArray(value)) return matcher(value); - return property(value); -} - -// External wrapper for our callback generator. Users may customize -// `_.iteratee` if they want additional predicate/iteratee shorthand styles. -// This abstraction hides the internal-only `argCount` argument. -function iteratee(value, context) { - return baseIteratee(value, context, Infinity); -} -_$1.iteratee = iteratee; - -// The function we call internally to generate a callback. It invokes -// `_.iteratee` if overridden, otherwise `baseIteratee`. -function cb(value, context, argCount) { - if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); - return baseIteratee(value, context, argCount); -} - -// Returns the results of applying the `iteratee` to each element of `obj`. -// In contrast to `_.map` it returns an object. -function mapObject(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = keys(obj), - length = _keys.length, - results = {}; - for (var index = 0; index < length; index++) { - var currentKey = _keys[index]; - results[currentKey] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Predicate-generating function. Often useful outside of Underscore. -function noop(){} - -// Generates a function for a given object that returns a given property. -function propertyOf(obj) { - if (obj == null) return noop; - return function(path) { - return get(obj, path); - }; -} - -// Run a function **n** times. -function times(n, iteratee, context) { - var accum = Array(Math.max(0, n)); - iteratee = optimizeCb(iteratee, context, 1); - for (var i = 0; i < n; i++) accum[i] = iteratee(i); - return accum; -} - -// Return a random integer between `min` and `max` (inclusive). -function random(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); -} - -// A (possibly faster) way to get the current timestamp as an integer. -var now = Date.now || function() { - return new Date().getTime(); -}; - -// Internal helper to generate functions for escaping and unescaping strings -// to/from HTML interpolation. -function createEscaper(map) { - var escaper = function(match) { - return map[match]; - }; - // Regexes for identifying a key that needs to be escaped. - var source = '(?:' + keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function(string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; -} - -// Internal list of HTML entities for escaping. -var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' -}; - -// Function for escaping strings to HTML interpolation. -var _escape = createEscaper(escapeMap); - -// Internal list of HTML entities for unescaping. -var unescapeMap = invert(escapeMap); - -// Function for unescaping strings from HTML interpolation. -var _unescape = createEscaper(unescapeMap); - -// By default, Underscore uses ERB-style template delimiters. Change the -// following template settings to use alternative delimiters. -var templateSettings = _$1.templateSettings = { - evaluate: /<%([\s\S]+?)%>/g, - interpolate: /<%=([\s\S]+?)%>/g, - escape: /<%-([\s\S]+?)%>/g -}; - -// When customizing `_.templateSettings`, if you don't want to define an -// interpolation, evaluation or escaping regex, we need one that is -// guaranteed not to match. -var noMatch = /(.)^/; - -// Certain characters need to be escaped so that they can be put into a -// string literal. -var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\u2028': 'u2028', - '\u2029': 'u2029' -}; - -var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; - -function escapeChar(match) { - return '\\' + escapes[match]; -} - -// In order to prevent third-party code injection through -// `_.templateSettings.variable`, we test it against the following regular -// expression. It is intentionally a bit more liberal than just matching valid -// identifiers, but still prevents possible loopholes through defaults or -// destructuring assignment. -var bareIdentifier = /^\s*(\w|\$)+\s*$/; - -// JavaScript micro-templating, similar to John Resig's implementation. -// Underscore templating handles arbitrary delimiters, preserves whitespace, -// and correctly escapes quotes within interpolated code. -// NB: `oldSettings` only exists for backwards compatibility. -function template(text, settings, oldSettings) { - if (!settings && oldSettings) settings = oldSettings; - settings = defaults({}, settings, _$1.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset).replace(escapeRegExp, escapeChar); - index = offset + match.length; - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } else if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } else if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - - // Adobe VMs need the match returned to produce the correct offset. - return match; - }); - source += "';\n"; - - var argument = settings.variable; - if (argument) { - // Insure against third-party code injection. (CVE-2021-23358) - if (!bareIdentifier.test(argument)) throw new Error( - 'variable is not a bare identifier: ' + argument - ); - } else { - // If a variable is not specified, place data values in local scope. - source = 'with(obj||{}){\n' + source + '}\n'; - argument = 'obj'; - } - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + 'return __p;\n'; - - var render; - try { - render = new Function(argument, '_', source); - } catch (e) { - e.source = source; - throw e; - } - - var template = function(data) { - return render.call(this, data, _$1); - }; - - // Provide the compiled source as a convenience for precompilation. - template.source = 'function(' + argument + '){\n' + source + '}'; - - return template; -} - -// Traverses the children of `obj` along `path`. If a child is a function, it -// is invoked with its parent as context. Returns the value of the final -// child, or `fallback` if any child is undefined. -function result(obj, path, fallback) { - path = toPath(path); - var length = path.length; - if (!length) { - return isFunction$1(fallback) ? fallback.call(obj) : fallback; - } - for (var i = 0; i < length; i++) { - var prop = obj == null ? void 0 : obj[path[i]]; - if (prop === void 0) { - prop = fallback; - i = length; // Ensure we don't continue iterating. + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); } - obj = isFunction$1(prop) ? prop.call(obj) : prop; - } - return obj; -} - -// Generate a unique integer id (unique within the entire client session). -// Useful for temporary DOM ids. -var idCounter = 0; -function uniqueId(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; -} - -// Start chaining a wrapped Underscore object. -function chain(obj) { - var instance = _$1(obj); - instance._chain = true; - return instance; -} - -// Internal function to execute `sourceFunc` bound to `context` with optional -// `args`. Determines whether to execute a function as a constructor or as a -// normal function. -function executeBound(sourceFunc, boundFunc, context, callingContext, args) { - if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); - var self = baseCreate(sourceFunc.prototype); - var result = sourceFunc.apply(self, args); - if (isObject(result)) return result; - return self; -} - -// Partially apply a function by creating a version that has had some of its -// arguments pre-filled, without changing its dynamic `this` context. `_` acts -// as a placeholder by default, allowing any combination of arguments to be -// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. -var partial = restArguments(function(func, boundArgs) { - var placeholder = partial.placeholder; - var bound = function() { - var position = 0, length = boundArgs.length; - var args = Array(length); - for (var i = 0; i < length; i++) { - args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; - } - while (position < arguments.length) args.push(arguments[position++]); - return executeBound(func, bound, this, this, args); - }; - return bound; -}); - -partial.placeholder = _$1; - -// Create a function bound to a given object (assigning `this`, and arguments, -// optionally). -var bind = restArguments(function(func, context, args) { - if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); - var bound = restArguments(function(callArgs) { - return executeBound(func, bound, context, this, args.concat(callArgs)); - }); - return bound; -}); - -// Internal helper for collection methods to determine whether a collection -// should be iterated as an array or as an object. -// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength -// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 -var isArrayLike = createSizePropertyCheck(getLength); - -// Internal implementation of a recursive `flatten` function. -function flatten$1(input, depth, strict, output) { - output = output || []; - if (!depth && depth !== 0) { - depth = Infinity; - } else if (depth <= 0) { - return output.concat(input); - } - var idx = output.length; - for (var i = 0, length = getLength(input); i < length; i++) { - var value = input[i]; - if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { - // Flatten current level of array or arguments object. - if (depth > 1) { - flatten$1(value, depth - 1, strict, output); - idx = output.length; - } else { - var j = 0, len = value.length; - while (j < len) output[idx++] = value[j++]; - } - } else if (!strict) { - output[idx++] = value; + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); } - } - return output; -} - -// Bind a number of an object's methods to that object. Remaining arguments -// are the method names to be bound. Useful for ensuring that all callbacks -// defined on an object belong to it. -var bindAll = restArguments(function(obj, keys) { - keys = flatten$1(keys, false, false); - var index = keys.length; - if (index < 1) throw new Error('bindAll must be passed function names'); - while (index--) { - var key = keys[index]; - obj[key] = bind(obj[key], obj); - } - return obj; -}); - -// Memoize an expensive function by storing its results. -function memoize(func, hasher) { - var memoize = function(key) { - var cache = memoize.cache; - var address = '' + (hasher ? hasher.apply(this, arguments) : key); - if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); - return cache[address]; - }; - memoize.cache = {}; - return memoize; -} - -// Delays a function for the given number of milliseconds, and then calls -// it with the arguments supplied. -var delay = restArguments(function(func, wait, args) { - return setTimeout(function() { - return func.apply(null, args); - }, wait); -}); - -// Defers a function, scheduling it to run after the current call stack has -// cleared. -var defer = partial(delay, _$1, 1); - -// Returns a function, that, when invoked, will only be triggered at most once -// during a given window of time. Normally, the throttled function will run -// as much as it can, without ever going more than once per `wait` duration; -// but if you'd like to disable the execution on the leading edge, pass -// `{leading: false}`. To disable execution on the trailing edge, ditto. -function throttle(func, wait, options) { - var timeout, context, args, result; - var previous = 0; - if (!options) options = {}; - - var later = function() { - previous = options.leading === false ? 0 : now(); - timeout = null; - result = func.apply(context, args); - if (!timeout) context = args = null; - }; - - var throttled = function() { - var _now = now(); - if (!previous && options.leading === false) previous = _now; - var remaining = wait - (_now - previous); - context = this; - args = arguments; - if (remaining <= 0 || remaining > wait) { - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - previous = _now; - result = func.apply(context, args); - if (!timeout) context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = setTimeout(later, remaining); + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); } - return result; - }; - - throttled.cancel = function() { - clearTimeout(timeout); - previous = 0; - timeout = context = args = null; - }; - - return throttled; -} - -// When a sequence of calls of the returned function ends, the argument -// function is triggered. The end of a sequence is defined by the `wait` -// parameter. If `immediate` is passed, the argument function will be -// triggered at the beginning of the sequence instead of at the end. -function debounce(func, wait, immediate) { - var timeout, previous, args, result, context; - - var later = function() { - var passed = now() - previous; - if (wait > passed) { - timeout = setTimeout(later, wait - passed); - } else { - timeout = null; - if (!immediate) result = func.apply(context, args); - // This check is needed because `func` can recursively invoke `debounced`. - if (!timeout) args = context = null; + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - }; - - var debounced = restArguments(function(_args) { - context = this; - args = _args; - previous = now(); - if (!timeout) { - timeout = setTimeout(later, wait); - if (immediate) result = func.apply(context, args); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - return result; - }); - - debounced.cancel = function() { - clearTimeout(timeout); - timeout = args = context = null; - }; - - return debounced; -} - -// Returns the first function passed as an argument to the second, -// allowing you to adjust arguments, run code before and after, and -// conditionally execute the original function. -function wrap(func, wrapper) { - return partial(wrapper, func); -} - -// Returns a negated version of the passed-in predicate. -function negate(predicate) { - return function() { - return !predicate.apply(this, arguments); - }; -} - -// Returns a function that is the composition of a list of functions, each -// consuming the return value of the function that follows. -function compose() { - var args = arguments; - var start = args.length - 1; - return function() { - var i = start; - var result = args[start].apply(this, arguments); - while (i--) result = args[i].call(this, result); - return result; - }; -} - -// Returns a function that will only be executed on and after the Nth call. -function after(times, func) { - return function() { - if (--times < 1) { - return func.apply(this, arguments); + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - }; -} - -// Returns a function that will only be executed up to (but not including) the -// Nth call. -function before(times, func) { - var memo; - return function() { - if (--times > 0) { - memo = func.apply(this, arguments); + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (times <= 1) func = null; - return memo; - }; -} - -// Returns a function that will be executed at most one time, no matter how -// often you call it. Useful for lazy initialization. -var once = partial(before, 2); - -// Returns the first key on an object that passes a truth test. -function findKey(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = keys(obj), key; - for (var i = 0, length = _keys.length; i < length; i++) { - key = _keys[i]; - if (predicate(obj[key], key, obj)) return key; - } -} - -// Internal function to generate `_.findIndex` and `_.findLastIndex`. -function createPredicateIndexFinder(dir) { - return function(array, predicate, context) { - predicate = cb(predicate, context); - var length = getLength(array); - var index = dir > 0 ? 0 : length - 1; - for (; index >= 0 && index < length; index += dir) { - if (predicate(array[index], index, array)) return index; + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); } - return -1; - }; -} - -// Returns the first index on an array-like that passes a truth test. -var findIndex = createPredicateIndexFinder(1); - -// Returns the last index on an array-like that passes a truth test. -var findLastIndex = createPredicateIndexFinder(-1); - -// Use a comparator function to figure out the smallest index at which -// an object should be inserted so as to maintain order. Uses binary search. -function sortedIndex(array, obj, iteratee, context) { - iteratee = cb(iteratee, context, 1); - var value = iteratee(obj); - var low = 0, high = getLength(array); - while (low < high) { - var mid = Math.floor((low + high) / 2); - if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; - } - return low; -} - -// Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. -function createIndexFinder(dir, predicateFind, sortedIndex) { - return function(array, item, idx) { - var i = 0, length = getLength(array); - if (typeof idx == 'number') { - if (dir > 0) { - i = idx >= 0 ? idx : Math.max(idx + length, i); - } else { - length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; - } - } else if (sortedIndex && idx && length) { - idx = sortedIndex(array, item); - return array[idx] === item ? idx : -1; + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); } - if (item !== item) { - idx = predicateFind(slice.call(array, i, length), isNaN$1); - return idx >= 0 ? idx + i : -1; + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); } - for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { - if (array[idx] === item) return idx; + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - return -1; - }; } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -// Return the position of the first occurrence of an item in an array, -// or -1 if the item is not included in the array. -// If the array is large and already in sort order, pass `true` -// for **isSorted** to use binary search. -var indexOf = createIndexFinder(1, findIndex, sortedIndex); - -// Return the position of the last occurrence of an item in an array, -// or -1 if the item is not included in the array. -var lastIndexOf = createIndexFinder(-1, findLastIndex); - -// Return the first value which passes a truth test. -function find(obj, predicate, context) { - var keyFinder = isArrayLike(obj) ? findIndex : findKey; - var key = keyFinder(obj, predicate, context); - if (key !== void 0 && key !== -1) return obj[key]; -} -// Convenience version of a common use case of `_.find`: getting the first -// object containing specific `key:value` pairs. -function findWhere(obj, attrs) { - return find(obj, matcher(attrs)); -} +/***/ }), -// The cornerstone for collection functions, an `each` -// implementation, aka `forEach`. -// Handles raw objects in addition to array-likes. Treats all -// sparse array-likes as if they were dense. -function each(obj, iteratee, context) { - iteratee = optimizeCb(iteratee, context); - var i, length; - if (isArrayLike(obj)) { - for (i = 0, length = obj.length; i < length; i++) { - iteratee(obj[i], i, obj); - } - } else { - var _keys = keys(obj); - for (i = 0, length = _keys.length; i < length; i++) { - iteratee(obj[_keys[i]], _keys[i], obj); - } - } - return obj; -} +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { -// Return the results of applying the iteratee to each element. -function map(obj, iteratee, context) { - iteratee = cb(iteratee, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - results = Array(length); - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - results[index] = iteratee(obj[currentKey], currentKey, obj); - } - return results; -} - -// Internal helper to create a reducing function, iterating left or right. -function createReduce(dir) { - // Wrap code that reassigns argument variables in a separate function than - // the one that accesses `arguments.length` to avoid a perf hit. (#1991) - var reducer = function(obj, iteratee, memo, initial) { - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length, - index = dir > 0 ? 0 : length - 1; - if (!initial) { - memo = obj[_keys ? _keys[index] : index]; - index += dir; - } - for (; index >= 0 && index < length; index += dir) { - var currentKey = _keys ? _keys[index] : index; - memo = iteratee(memo, obj[currentKey], currentKey, obj); - } - return memo; - }; +"use strict"; - return function(obj, iteratee, memo, context) { - var initial = arguments.length >= 3; - return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); - }; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -// **Reduce** builds up a single result from a list of values, aka `inject`, -// or `foldl`. -var reduce = createReduce(1); -// The right-associative version of reduce, also known as `foldr`. -var reduceRight = createReduce(-1); - -// Return all the elements that pass a truth test. -function filter(obj, predicate, context) { - var results = []; - predicate = cb(predicate, context); - each(obj, function(value, index, list) { - if (predicate(value, index, list)) results.push(value); - }); - return results; -} +/***/ }), -// Return all the elements for which a truth test fails. -function reject(obj, predicate, context) { - return filter(obj, negate(cb(predicate)), context); -} +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { -// Determine whether all of the elements pass a truth test. -function every(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (!predicate(obj[currentKey], currentKey, obj)) return false; - } - return true; -} +"use strict"; -// Determine if at least one element in the object passes a truth test. -function some(obj, predicate, context) { - predicate = cb(predicate, context); - var _keys = !isArrayLike(obj) && keys(obj), - length = (_keys || obj).length; - for (var index = 0; index < length; index++) { - var currentKey = _keys ? _keys[index] : index; - if (predicate(obj[currentKey], currentKey, obj)) return true; - } - return false; +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; -// Determine if the array or object contains a given item (using `===`). -function contains(obj, item, fromIndex, guard) { - if (!isArrayLike(obj)) obj = values(obj); - if (typeof fromIndex != 'number' || guard) fromIndex = 0; - return indexOf(obj, item, fromIndex) >= 0; -} -// Invoke a method (with arguments) on every item in a collection. -var invoke = restArguments(function(obj, path, args) { - var contextPath, func; - if (isFunction$1(path)) { - func = path; - } else { - path = toPath(path); - contextPath = path.slice(0, -1); - path = path[path.length - 1]; - } - return map(obj, function(context) { - var method = func; - if (!method) { - if (contextPath && contextPath.length) { - context = deepGet(context, contextPath); - } - if (context == null) return void 0; - method = context[path]; - } - return method == null ? method : method.apply(context, args); - }); -}); +/***/ }), -// Convenience version of a common use case of `_.map`: fetching a property. -function pluck(obj, key) { - return map(obj, property(key)); -} +/***/ 2877: +/***/ ((module) => { -// Convenience version of a common use case of `_.filter`: selecting only -// objects containing specific `key:value` pairs. -function where(obj, attrs) { - return filter(obj, matcher(attrs)); -} +module.exports = eval("require")("encoding"); -// Return the maximum element (or element-based computation). -function max(obj, iteratee, context) { - var result = -Infinity, lastComputed = -Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value > result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} -// Return the minimum element (or element-based computation). -function min(obj, iteratee, context) { - var result = Infinity, lastComputed = Infinity, - value, computed; - if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) { - obj = isArrayLike(obj) ? obj : values(obj); - for (var i = 0, length = obj.length; i < length; i++) { - value = obj[i]; - if (value != null && value < result) { - result = value; - } - } - } else { - iteratee = cb(iteratee, context); - each(obj, function(v, index, list) { - computed = iteratee(v, index, list); - if (computed < lastComputed || (computed === Infinity && result === Infinity)) { - result = v; - lastComputed = computed; - } - }); - } - return result; -} +/***/ }), -// Safely create a real, live array from anything iterable. -var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; -function toArray(obj) { - if (!obj) return []; - if (isArray(obj)) return slice.call(obj); - if (isString(obj)) { - // Keep surrogate pair characters together. - return obj.match(reStrSymbol); - } - if (isArrayLike(obj)) return map(obj, identity); - return values(obj); -} +/***/ 9491: +/***/ ((module) => { -// Sample **n** random values from a collection using the modern version of the -// [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). -// If **n** is not specified, returns a single random element. -// The internal `guard` argument allows it to work with `_.map`. -function sample(obj, n, guard) { - if (n == null || guard) { - if (!isArrayLike(obj)) obj = values(obj); - return obj[random(obj.length - 1)]; - } - var sample = toArray(obj); - var length = getLength(sample); - n = Math.max(Math.min(n, length), 0); - var last = length - 1; - for (var index = 0; index < n; index++) { - var rand = random(index, last); - var temp = sample[index]; - sample[index] = sample[rand]; - sample[rand] = temp; - } - return sample.slice(0, n); -} +"use strict"; +module.exports = require("assert"); -// Shuffle a collection. -function shuffle(obj) { - return sample(obj, Infinity); -} +/***/ }), -// Sort the object's values by a criterion produced by an iteratee. -function sortBy(obj, iteratee, context) { - var index = 0; - iteratee = cb(iteratee, context); - return pluck(map(obj, function(value, key, list) { - return { - value: value, - index: index++, - criteria: iteratee(value, key, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index - right.index; - }), 'value'); -} - -// An internal function used for aggregate "group by" operations. -function group(behavior, partition) { - return function(obj, iteratee, context) { - var result = partition ? [[], []] : {}; - iteratee = cb(iteratee, context); - each(obj, function(value, index) { - var key = iteratee(value, index, obj); - behavior(result, value, key); - }); - return result; - }; -} +/***/ 6113: +/***/ ((module) => { -// Groups the object's values by a criterion. Pass either a string attribute -// to group by, or a function that returns the criterion. -var groupBy = group(function(result, value, key) { - if (has$1(result, key)) result[key].push(value); else result[key] = [value]; -}); +"use strict"; +module.exports = require("crypto"); -// Indexes the object's values by a criterion, similar to `_.groupBy`, but for -// when you know that your index values will be unique. -var indexBy = group(function(result, value, key) { - result[key] = value; -}); +/***/ }), -// Counts instances of an object that group by a certain criterion. Pass -// either a string attribute to count by, or a function that returns the -// criterion. -var countBy = group(function(result, value, key) { - if (has$1(result, key)) result[key]++; else result[key] = 1; -}); +/***/ 2361: +/***/ ((module) => { -// Split a collection into two arrays: one whose elements all pass the given -// truth test, and one whose elements all do not pass the truth test. -var partition = group(function(result, value, pass) { - result[pass ? 0 : 1].push(value); -}, true); +"use strict"; +module.exports = require("events"); -// Return the number of elements in a collection. -function size(obj) { - if (obj == null) return 0; - return isArrayLike(obj) ? obj.length : keys(obj).length; -} +/***/ }), -// Internal `_.pick` helper function to determine whether `key` is an enumerable -// property name of `obj`. -function keyInObj(value, key, obj) { - return key in obj; -} +/***/ 7147: +/***/ ((module) => { -// Return a copy of the object only containing the allowed properties. -var pick = restArguments(function(obj, keys) { - var result = {}, iteratee = keys[0]; - if (obj == null) return result; - if (isFunction$1(iteratee)) { - if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); - keys = allKeys(obj); - } else { - iteratee = keyInObj; - keys = flatten$1(keys, false, false); - obj = Object(obj); - } - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i]; - var value = obj[key]; - if (iteratee(value, key, obj)) result[key] = value; - } - return result; -}); +"use strict"; +module.exports = require("fs"); -// Return a copy of the object without the disallowed properties. -var omit = restArguments(function(obj, keys) { - var iteratee = keys[0], context; - if (isFunction$1(iteratee)) { - iteratee = negate(iteratee); - if (keys.length > 1) context = keys[1]; - } else { - keys = map(flatten$1(keys, false, false), String); - iteratee = function(value, key) { - return !contains(keys, key); - }; - } - return pick(obj, iteratee, context); -}); +/***/ }), -// Returns everything but the last entry of the array. Especially useful on -// the arguments object. Passing **n** will return all the values in -// the array, excluding the last N. -function initial(array, n, guard) { - return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); -} +/***/ 3685: +/***/ ((module) => { -// Get the first element of an array. Passing **n** will return the first N -// values in the array. The **guard** check allows it to work with `_.map`. -function first(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[0]; - return initial(array, array.length - n); -} +"use strict"; +module.exports = require("http"); -// Returns everything but the first entry of the `array`. Especially useful on -// the `arguments` object. Passing an **n** will return the rest N values in the -// `array`. -function rest(array, n, guard) { - return slice.call(array, n == null || guard ? 1 : n); -} +/***/ }), -// Get the last element of an array. Passing **n** will return the last N -// values in the array. -function last(array, n, guard) { - if (array == null || array.length < 1) return n == null || guard ? void 0 : []; - if (n == null || guard) return array[array.length - 1]; - return rest(array, Math.max(0, array.length - n)); -} +/***/ 5687: +/***/ ((module) => { -// Trim out all falsy values from an array. -function compact(array) { - return filter(array, Boolean); -} +"use strict"; +module.exports = require("https"); -// Flatten out an array, either recursively (by default), or up to `depth`. -// Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. -function flatten(array, depth) { - return flatten$1(array, depth, false); -} +/***/ }), -// Take the difference between one array and a number of other arrays. -// Only the elements present in just the first array will remain. -var difference = restArguments(function(array, rest) { - rest = flatten$1(rest, true, true); - return filter(array, function(value){ - return !contains(rest, value); - }); -}); +/***/ 1808: +/***/ ((module) => { -// Return a version of the array that does not contain the specified value(s). -var without = restArguments(function(array, otherArrays) { - return difference(array, otherArrays); -}); +"use strict"; +module.exports = require("net"); -// Produce a duplicate-free version of the array. If the array has already -// been sorted, you have the option of using a faster algorithm. -// The faster algorithm will not work with an iteratee if the iteratee -// is not a one-to-one function, so providing an iteratee will disable -// the faster algorithm. -function uniq(array, isSorted, iteratee, context) { - if (!isBoolean(isSorted)) { - context = iteratee; - iteratee = isSorted; - isSorted = false; - } - if (iteratee != null) iteratee = cb(iteratee, context); - var result = []; - var seen = []; - for (var i = 0, length = getLength(array); i < length; i++) { - var value = array[i], - computed = iteratee ? iteratee(value, i, array) : value; - if (isSorted && !iteratee) { - if (!i || seen !== computed) result.push(value); - seen = computed; - } else if (iteratee) { - if (!contains(seen, computed)) { - seen.push(computed); - result.push(value); - } - } else if (!contains(result, value)) { - result.push(value); - } - } - return result; -} +/***/ }), -// Produce an array that contains the union: each distinct element from all of -// the passed-in arrays. -var union = restArguments(function(arrays) { - return uniq(flatten$1(arrays, true, true)); -}); +/***/ 2037: +/***/ ((module) => { -// Produce an array that contains every item shared between all the -// passed-in arrays. -function intersection(array) { - var result = []; - var argsLength = arguments.length; - for (var i = 0, length = getLength(array); i < length; i++) { - var item = array[i]; - if (contains(result, item)) continue; - var j; - for (j = 1; j < argsLength; j++) { - if (!contains(arguments[j], item)) break; - } - if (j === argsLength) result.push(item); - } - return result; -} +"use strict"; +module.exports = require("os"); -// Complement of zip. Unzip accepts an array of arrays and groups -// each array's elements on shared indices. -function unzip(array) { - var length = (array && max(array, getLength).length) || 0; - var result = Array(length); +/***/ }), - for (var index = 0; index < length; index++) { - result[index] = pluck(array, index); - } - return result; -} +/***/ 1017: +/***/ ((module) => { -// Zip together multiple lists into a single array -- elements that share -// an index go together. -var zip = restArguments(unzip); +"use strict"; +module.exports = require("path"); -// Converts lists into objects. Pass either a single array of `[key, value]` -// pairs, or two parallel arrays of the same length -- one of keys, and one of -// the corresponding values. Passing by pairs is the reverse of `_.pairs`. -function object(list, values) { - var result = {}; - for (var i = 0, length = getLength(list); i < length; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; -} +/***/ }), -// Generate an integer Array containing an arithmetic progression. A port of -// the native Python `range()` function. See -// [the Python documentation](https://docs.python.org/library/functions.html#range). -function range(start, stop, step) { - if (stop == null) { - stop = start || 0; - start = 0; - } - if (!step) { - step = stop < start ? -1 : 1; - } +/***/ 5477: +/***/ ((module) => { - var length = Math.max(Math.ceil((stop - start) / step), 0); - var range = Array(length); +"use strict"; +module.exports = require("punycode"); - for (var idx = 0; idx < length; idx++, start += step) { - range[idx] = start; - } +/***/ }), - return range; -} +/***/ 2781: +/***/ ((module) => { -// Chunk a single array into multiple arrays, each containing `count` or fewer -// items. -function chunk(array, count) { - if (count == null || count < 1) return []; - var result = []; - var i = 0, length = array.length; - while (i < length) { - result.push(slice.call(array, i, i += count)); - } - return result; -} +"use strict"; +module.exports = require("stream"); -// Helper function to continue chaining intermediate results. -function chainResult(instance, obj) { - return instance._chain ? _$1(obj).chain() : obj; -} +/***/ }), -// Add your own custom functions to the Underscore object. -function mixin(obj) { - each(functions(obj), function(name) { - var func = _$1[name] = obj[name]; - _$1.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return chainResult(this, func.apply(_$1, args)); - }; - }); - return _$1; -} - -// Add all mutator `Array` functions to the wrapper. -each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) { - method.apply(obj, arguments); - if ((name === 'shift' || name === 'splice') && obj.length === 0) { - delete obj[0]; - } - } - return chainResult(this, obj); - }; -}); +/***/ 4404: +/***/ ((module) => { -// Add all accessor `Array` functions to the wrapper. -each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _$1.prototype[name] = function() { - var obj = this._wrapped; - if (obj != null) obj = method.apply(obj, arguments); - return chainResult(this, obj); - }; -}); +"use strict"; +module.exports = require("tls"); -// Named Exports - -var allExports = { - __proto__: null, - VERSION: VERSION, - restArguments: restArguments, - isObject: isObject, - isNull: isNull, - isUndefined: isUndefined, - isBoolean: isBoolean, - isElement: isElement, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isRegExp: isRegExp, - isError: isError, - isSymbol: isSymbol, - isArrayBuffer: isArrayBuffer, - isDataView: isDataView$1, - isArray: isArray, - isFunction: isFunction$1, - isArguments: isArguments$1, - isFinite: isFinite$1, - isNaN: isNaN$1, - isTypedArray: isTypedArray$1, - isEmpty: isEmpty, - isMatch: isMatch, - isEqual: isEqual, - isMap: isMap, - isWeakMap: isWeakMap, - isSet: isSet, - isWeakSet: isWeakSet, - keys: keys, - allKeys: allKeys, - values: values, - pairs: pairs, - invert: invert, - functions: functions, - methods: functions, - extend: extend, - extendOwn: extendOwn, - assign: extendOwn, - defaults: defaults, - create: create, - clone: clone, - tap: tap, - get: get, - has: has, - mapObject: mapObject, - identity: identity, - constant: constant, - noop: noop, - toPath: toPath$1, - property: property, - propertyOf: propertyOf, - matcher: matcher, - matches: matcher, - times: times, - random: random, - now: now, - escape: _escape, - unescape: _unescape, - templateSettings: templateSettings, - template: template, - result: result, - uniqueId: uniqueId, - chain: chain, - iteratee: iteratee, - partial: partial, - bind: bind, - bindAll: bindAll, - memoize: memoize, - delay: delay, - defer: defer, - throttle: throttle, - debounce: debounce, - wrap: wrap, - negate: negate, - compose: compose, - after: after, - before: before, - once: once, - findKey: findKey, - findIndex: findIndex, - findLastIndex: findLastIndex, - sortedIndex: sortedIndex, - indexOf: indexOf, - lastIndexOf: lastIndexOf, - find: find, - detect: find, - findWhere: findWhere, - each: each, - forEach: each, - map: map, - collect: map, - reduce: reduce, - foldl: reduce, - inject: reduce, - reduceRight: reduceRight, - foldr: reduceRight, - filter: filter, - select: filter, - reject: reject, - every: every, - all: every, - some: some, - any: some, - contains: contains, - includes: contains, - include: contains, - invoke: invoke, - pluck: pluck, - where: where, - max: max, - min: min, - shuffle: shuffle, - sample: sample, - sortBy: sortBy, - groupBy: groupBy, - indexBy: indexBy, - countBy: countBy, - partition: partition, - toArray: toArray, - size: size, - pick: pick, - omit: omit, - first: first, - head: first, - take: first, - initial: initial, - last: last, - rest: rest, - tail: rest, - drop: rest, - compact: compact, - flatten: flatten, - without: without, - uniq: uniq, - unique: uniq, - union: union, - intersection: intersection, - difference: difference, - unzip: unzip, - transpose: unzip, - zip: zip, - object: object, - range: range, - chunk: chunk, - mixin: mixin, - 'default': _$1 -}; +/***/ }), -// Default Export - -// Add all of the Underscore functions to the wrapper object. -var _ = mixin(allExports); -// Legacy Node.js API. -_._ = _; - -exports.VERSION = VERSION; -exports._ = _; -exports._escape = _escape; -exports._unescape = _unescape; -exports.after = after; -exports.allKeys = allKeys; -exports.before = before; -exports.bind = bind; -exports.bindAll = bindAll; -exports.chain = chain; -exports.chunk = chunk; -exports.clone = clone; -exports.compact = compact; -exports.compose = compose; -exports.constant = constant; -exports.contains = contains; -exports.countBy = countBy; -exports.create = create; -exports.debounce = debounce; -exports.defaults = defaults; -exports.defer = defer; -exports.delay = delay; -exports.difference = difference; -exports.each = each; -exports.every = every; -exports.extend = extend; -exports.extendOwn = extendOwn; -exports.filter = filter; -exports.find = find; -exports.findIndex = findIndex; -exports.findKey = findKey; -exports.findLastIndex = findLastIndex; -exports.findWhere = findWhere; -exports.first = first; -exports.flatten = flatten; -exports.functions = functions; -exports.get = get; -exports.groupBy = groupBy; -exports.has = has; -exports.identity = identity; -exports.indexBy = indexBy; -exports.indexOf = indexOf; -exports.initial = initial; -exports.intersection = intersection; -exports.invert = invert; -exports.invoke = invoke; -exports.isArguments = isArguments$1; -exports.isArray = isArray; -exports.isArrayBuffer = isArrayBuffer; -exports.isBoolean = isBoolean; -exports.isDataView = isDataView$1; -exports.isDate = isDate; -exports.isElement = isElement; -exports.isEmpty = isEmpty; -exports.isEqual = isEqual; -exports.isError = isError; -exports.isFinite = isFinite$1; -exports.isFunction = isFunction$1; -exports.isMap = isMap; -exports.isMatch = isMatch; -exports.isNaN = isNaN$1; -exports.isNull = isNull; -exports.isNumber = isNumber; -exports.isObject = isObject; -exports.isRegExp = isRegExp; -exports.isSet = isSet; -exports.isString = isString; -exports.isSymbol = isSymbol; -exports.isTypedArray = isTypedArray$1; -exports.isUndefined = isUndefined; -exports.isWeakMap = isWeakMap; -exports.isWeakSet = isWeakSet; -exports.iteratee = iteratee; -exports.keys = keys; -exports.last = last; -exports.lastIndexOf = lastIndexOf; -exports.map = map; -exports.mapObject = mapObject; -exports.matcher = matcher; -exports.max = max; -exports.memoize = memoize; -exports.min = min; -exports.mixin = mixin; -exports.negate = negate; -exports.noop = noop; -exports.now = now; -exports.object = object; -exports.omit = omit; -exports.once = once; -exports.pairs = pairs; -exports.partial = partial; -exports.partition = partition; -exports.pick = pick; -exports.pluck = pluck; -exports.property = property; -exports.propertyOf = propertyOf; -exports.random = random; -exports.range = range; -exports.reduce = reduce; -exports.reduceRight = reduceRight; -exports.reject = reject; -exports.rest = rest; -exports.restArguments = restArguments; -exports.result = result; -exports.sample = sample; -exports.shuffle = shuffle; -exports.size = size; -exports.some = some; -exports.sortBy = sortBy; -exports.sortedIndex = sortedIndex; -exports.tap = tap; -exports.template = template; -exports.templateSettings = templateSettings; -exports.throttle = throttle; -exports.times = times; -exports.toArray = toArray; -exports.toPath = toPath$1; -exports.union = union; -exports.uniq = uniq; -exports.uniqueId = uniqueId; -exports.unzip = unzip; -exports.values = values; -exports.where = where; -exports.without = without; -exports.wrap = wrap; -exports.zip = zip; -//# sourceMappingURL=underscore-node-f.cjs.map +/***/ 7310: +/***/ ((module) => { +"use strict"; +module.exports = require("url"); /***/ }), -/***/ 5067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -// Underscore.js 1.13.6 -// https://underscorejs.org -// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors -// Underscore may be freely distributed under the MIT license. - -var underscoreNodeF = __nccwpck_require__(6717); +/***/ 3837: +/***/ ((module) => { +"use strict"; +module.exports = require("util"); +/***/ }), -module.exports = underscoreNodeF._; -//# sourceMappingURL=underscore-node.cjs.map +/***/ 9796: +/***/ ((module) => { +"use strict"; +module.exports = require("zlib"); /***/ }), @@ -16008,7 +12155,7 @@ var __webpack_exports__ = {}; const core = __nccwpck_require__(2186); const github = __nccwpck_require__(5438); const https = __nccwpck_require__(5687); -const GitHubUtils = __nccwpck_require__(7999); +const GitHubUtils = __nccwpck_require__(9296); const pathToReviewerChecklist = 'https://raw.githubusercontent.com/Expensify/App/main/contributingGuides/REVIEWER_CHECKLIST.md'; const reviewerChecklistContains = '# Reviewer Checklist'; diff --git a/.github/actions/javascript/verifySignedCommits/index.js b/.github/actions/javascript/verifySignedCommits/index.js index ba188d3a2b86..26c0757dcde7 100644 --- a/.github/actions/javascript/verifySignedCommits/index.js +++ b/.github/actions/javascript/verifySignedCommits/index.js @@ -28,784 +28,238 @@ module.exports = CONST; /***/ }), -/***/ 7999: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -const _ = __nccwpck_require__(5067); -const lodashGet = __nccwpck_require__(6908); -const core = __nccwpck_require__(2186); -const {GitHub, getOctokitOptions} = __nccwpck_require__(3030); -const {throttling} = __nccwpck_require__(9968); -const {paginateRest} = __nccwpck_require__(4193); -const CONST = __nccwpck_require__(4097); +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); /** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; } - this.initOctokit(); - return this.internalOctokit.graphql; + this.command = command; + this.properties = properties; + this.message = message; } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } } - this.initOctokit(); - return this.internalOctokit.paginate; + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } +/***/ }), - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - return this.getStagingDeployCashData(data[0]); - }); - } +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} + * A code indicating that the action was successful */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - + ExitCode[ExitCode["Success"] = 0] = "Success"; /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] + * A code indicating that the action was a failure */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); + else { + command_1.issueCommand('add-path', {}, inputPath); } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); + if (options && options.trimWhitespace === false) { + return val; } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; - - -/***/ }), - -/***/ 7351: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.issue = exports.issueCommand = void 0; -const os = __importStar(__nccwpck_require__(2037)); -const utils_1 = __nccwpck_require__(5278); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } - } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; - } -} -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 2186: -/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { - -"use strict"; - -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; -const command_1 = __nccwpck_require__(7351); -const file_command_1 = __nccwpck_require__(717); -const utils_1 = __nccwpck_require__(5278); -const os = __importStar(__nccwpck_require__(2037)); -const path = __importStar(__nccwpck_require__(1017)); -const oidc_utils_1 = __nccwpck_require__(8041); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); - } - command_1.issueCommand('set-env', { name }, convertedVal); -} -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); -} -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueFileCommand('PATH', inputPath); - } - else { - command_1.issueCommand('add-path', {}, inputPath); - } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. - * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. - * Returns an empty string if the value is not defined. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - if (options && options.trimWhitespace === false) { - return val; - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Gets the values of an multiline input. Each value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string[] - * - */ -function getMultilineInput(name, options) { - const inputs = getInput(name, options) - .split('\n') - .filter(x => x !== ''); - if (options && options.trimWhitespace === false) { - return inputs; - } - return inputs.map(input => input.trim()); + return inputs.map(input => input.trim()); } exports.getMultilineInput = getMultilineInput; /** @@ -4865,3874 +4319,2264 @@ const Endpoints = { }, secretScanning: { getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], - listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], - listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], - listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], - listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], - updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] - }, - teams: { - addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], - addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - create: ["POST /orgs/{org}/teams"], - createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], - deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], - getByName: ["GET /orgs/{org}/teams/{team_slug}"], - getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], - list: ["GET /orgs/{org}/teams"], - listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], - listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], - listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], - listForAuthenticatedUser: ["GET /user/teams"], - listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], - listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], - listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], - listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], - removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], - removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], - removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], - updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], - updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], - updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] - }, - users: { - addEmailForAuthenticated: ["POST /user/emails", {}, { - renamed: ["users", "addEmailForAuthenticatedUser"] - }], - addEmailForAuthenticatedUser: ["POST /user/emails"], - block: ["PUT /user/blocks/{username}"], - checkBlocked: ["GET /user/blocks/{username}"], - checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], - checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], - createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { - renamed: ["users", "createGpgKeyForAuthenticatedUser"] - }], - createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], - createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { - renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] - }], - createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], - deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { - renamed: ["users", "deleteEmailForAuthenticatedUser"] - }], - deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], - deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] - }], - deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], - deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { - renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] - }], - deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], - follow: ["PUT /user/following/{username}"], - getAuthenticated: ["GET /user"], - getByUsername: ["GET /users/{username}"], - getContextForUser: ["GET /users/{username}/hovercard"], - getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { - renamed: ["users", "getGpgKeyForAuthenticatedUser"] - }], - getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], - getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { - renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] - }], - getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], - list: ["GET /users"], - listBlockedByAuthenticated: ["GET /user/blocks", {}, { - renamed: ["users", "listBlockedByAuthenticatedUser"] - }], - listBlockedByAuthenticatedUser: ["GET /user/blocks"], - listEmailsForAuthenticated: ["GET /user/emails", {}, { - renamed: ["users", "listEmailsForAuthenticatedUser"] - }], - listEmailsForAuthenticatedUser: ["GET /user/emails"], - listFollowedByAuthenticated: ["GET /user/following", {}, { - renamed: ["users", "listFollowedByAuthenticatedUser"] - }], - listFollowedByAuthenticatedUser: ["GET /user/following"], - listFollowersForAuthenticatedUser: ["GET /user/followers"], - listFollowersForUser: ["GET /users/{username}/followers"], - listFollowingForUser: ["GET /users/{username}/following"], - listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { - renamed: ["users", "listGpgKeysForAuthenticatedUser"] - }], - listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], - listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], - listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { - renamed: ["users", "listPublicEmailsForAuthenticatedUser"] - }], - listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], - listPublicKeysForUser: ["GET /users/{username}/keys"], - listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { - renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] - }], - listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], - setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { - renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] - }], - setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], - unblock: ["DELETE /user/blocks/{username}"], - unfollow: ["DELETE /user/following/{username}"], - updateAuthenticated: ["PATCH /user"] - } -}; - -const VERSION = "5.16.2"; - -function endpointsToMethods(octokit, endpointsMap) { - const newMethods = {}; - - for (const [scope, endpoints] of Object.entries(endpointsMap)) { - for (const [methodName, endpoint] of Object.entries(endpoints)) { - const [route, defaults, decorations] = endpoint; - const [method, url] = route.split(/ /); - const endpointDefaults = Object.assign({ - method, - url - }, defaults); - - if (!newMethods[scope]) { - newMethods[scope] = {}; - } - - const scopeMethods = newMethods[scope]; - - if (decorations) { - scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); - continue; - } - - scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); - } - } - - return newMethods; -} - -function decorate(octokit, scope, methodName, defaults, decorations) { - const requestWithDefaults = octokit.request.defaults(defaults); - /* istanbul ignore next */ - - function withDecorations(...args) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` - - if (decorations.mapToData) { - options = Object.assign({}, options, { - data: options[decorations.mapToData], - [decorations.mapToData]: undefined - }); - return requestWithDefaults(options); - } - - if (decorations.renamed) { - const [newScope, newMethodName] = decorations.renamed; - octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); - } - - if (decorations.deprecated) { - octokit.log.warn(decorations.deprecated); - } - - if (decorations.renamedParameters) { - // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - const options = requestWithDefaults.endpoint.merge(...args); - - for (const [name, alias] of Object.entries(decorations.renamedParameters)) { - if (name in options) { - octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); - - if (!(alias in options)) { - options[alias] = options[name]; - } - - delete options[name]; - } - } - - return requestWithDefaults(options); - } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - - - return requestWithDefaults(...args); - } - - return Object.assign(withDecorations, requestWithDefaults); -} - -function restEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return { - rest: api - }; -} -restEndpointMethods.VERSION = VERSION; -function legacyRestEndpointMethods(octokit) { - const api = endpointsToMethods(octokit, Endpoints); - return _objectSpread2(_objectSpread2({}, api), {}, { - rest: api - }); -} -legacyRestEndpointMethods.VERSION = VERSION; - -exports.legacyRestEndpointMethods = legacyRestEndpointMethods; -exports.restEndpointMethods = restEndpointMethods; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 9968: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); - -const VERSION = "4.1.0"; - -const noop = () => Promise.resolve(); // @ts-expect-error - - -function wrapRequest(state, request, options) { - return state.retryLimiter.schedule(doRequest, state, request, options); -} // @ts-expect-error - -async function doRequest(state, request, options) { - const isWrite = options.method !== "GET" && options.method !== "HEAD"; - const { - pathname - } = new URL(options.url, "http://github.test"); - const isSearch = options.method === "GET" && pathname.startsWith("/search/"); - const isGraphQL = pathname.startsWith("/graphql"); - const retryCount = ~~options.request.retryCount; - const jobOptions = retryCount > 0 ? { - priority: 0, - weight: 0 - } : {}; - - if (state.clustering) { - // Remove a job from Redis if it has not completed or failed within 60s - // Examples: Node process terminated, client disconnected, etc. - // @ts-expect-error - jobOptions.expiration = 1000 * 60; - } // Guarantee at least 1000ms between writes - // GraphQL can also trigger writes - - - if (isWrite || isGraphQL) { - await state.write.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 3000ms between requests that trigger notifications - - - if (isWrite && state.triggersNotification(pathname)) { - await state.notifications.key(state.id).schedule(jobOptions, noop); - } // Guarantee at least 2000ms between search requests - - - if (isSearch) { - await state.search.key(state.id).schedule(jobOptions, noop); - } - - const req = state.global.key(state.id).schedule(jobOptions, request, options); - - if (isGraphQL) { - const res = await req; - - if (res.data.errors != null && // @ts-expect-error - res.data.errors.some(error => error.type === "RATE_LIMITED")) { - const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { - response: res, - data: res.data - }); - throw error; - } - } - - return req; -} - -var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; - -function routeMatcher(paths) { - // EXAMPLE. For the following paths: - - /* [ - "/orgs/{org}/invitations", - "/repos/{owner}/{repo}/collaborators/{username}" - ] */ - const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: - - /* [ - '/orgs/(?:.+?)/invitations', - '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' - ] */ - - const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: - - /* - ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ - It may look scary, but paste it into https://www.debuggex.com/ - and it will make a lot more sense! - */ - - return new RegExp(regex, "i"); -} - -// @ts-expect-error - -const regex = routeMatcher(triggersNotificationPaths); -const triggersNotification = regex.test.bind(regex); -const groups = {}; // @ts-expect-error - -const createGroups = function (Bottleneck, common) { - groups.global = new Bottleneck.Group({ - id: "octokit-global", - maxConcurrent: 10, - ...common - }); - groups.search = new Bottleneck.Group({ - id: "octokit-search", - maxConcurrent: 1, - minTime: 2000, - ...common - }); - groups.write = new Bottleneck.Group({ - id: "octokit-write", - maxConcurrent: 1, - minTime: 1000, - ...common - }); - groups.notifications = new Bottleneck.Group({ - id: "octokit-notifications", - maxConcurrent: 1, - minTime: 3000, - ...common - }); -}; - -function throttling(octokit, octokitOptions) { - const { - enabled = true, - Bottleneck = BottleneckLight, - id = "no-id", - timeout = 1000 * 60 * 2, - // Redis TTL: 2 minutes - connection - } = octokitOptions.throttle || {}; - - if (!enabled) { - return {}; - } - - const common = { - connection, - timeout - }; - - if (groups.global == null) { - createGroups(Bottleneck, common); - } - - const state = Object.assign({ - clustering: connection != null, - triggersNotification, - minimumSecondaryRateRetryAfter: 5, - retryAfterBaseValue: 1000, - retryLimiter: new Bottleneck(), - id, - ...groups - }, octokitOptions.throttle); - const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; - - if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { - throw new Error(`octokit/plugin-throttling error: - You must pass the onSecondaryRateLimit and onRateLimit error handlers. - See https://github.com/octokit/rest.js#throttling - - const octokit = new Octokit({ - throttle: { - onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, - onRateLimit: (retryAfter, options) => {/* ... */} - } - }) - `); - } - - const events = {}; - const emitter = new Bottleneck.Events(events); // @ts-expect-error - - events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { - octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); - return state.onAbuseLimit(...args); - } : state.onSecondaryRateLimit); // @ts-expect-error - - events.on("rate-limit", state.onRateLimit); // @ts-expect-error - - events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error - - state.retryLimiter.on("failed", async function (error, info) { - const options = info.args[info.args.length - 1]; - const { - pathname - } = new URL(options.url, "http://github.test"); - const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - - if (!(shouldRetryGraphQL || error.status === 403)) { - return; - } - - const retryCount = ~~options.request.retryCount; - options.request.retryCount = retryCount; - const { - wantRetry, - retryAfter = 0 - } = await async function () { - if (/\bsecondary rate\b/i.test(error.message)) { - // The user has hit the secondary rate limit. (REST and GraphQL) - // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits - // The Retry-After header can sometimes be blank when hitting a secondary rate limit, - // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. - const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); - const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { - // The user has used all their allowed calls for the current time period (REST and GraphQL) - // https://docs.github.com/en/rest/reference/rate-limit (REST) - // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) - const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); - const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); - const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); - return { - wantRetry, - retryAfter - }; - } - - return {}; - }(); - - if (wantRetry) { - options.request.retryCount++; - return retryAfter * state.retryAfterBaseValue; - } - }); - octokit.hook.wrap("request", wrapRequest.bind(null, state)); - return {}; -} -throttling.VERSION = VERSION; -throttling.triggersNotification = triggersNotification; - -exports.throttling = throttling; -//# sourceMappingURL=index.js.map - - -/***/ }), - -/***/ 3682: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) - -// bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) - -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) -} - -function HookSingular () { - var singularHookName = 'h' - var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook -} - -function HookCollection () { - var state = { - registry: {} - } - - var hook = register.bind(null, state) - bindApi(hook, state) - - return hook -} - -var collectionHookDeprecationMessageDisplayed = false -function Hook () { - if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true - } - return HookCollection() -} - -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() - -module.exports = Hook -// expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection - - -/***/ }), - -/***/ 5549: -/***/ ((module) => { - -module.exports = addHook; - -function addHook(state, kind, name, hook) { - var orig = hook; - if (!state.registry[name]) { - state.registry[name] = []; - } - - if (kind === "before") { - hook = function (method, options) { - return Promise.resolve() - .then(orig.bind(null, options)) - .then(method.bind(null, options)); - }; - } - - if (kind === "after") { - hook = function (method, options) { - var result; - return Promise.resolve() - .then(method.bind(null, options)) - .then(function (result_) { - result = result_; - return orig(result, options); - }) - .then(function () { - return result; - }); - }; - } - - if (kind === "error") { - hook = function (method, options) { - return Promise.resolve() - .then(method.bind(null, options)) - .catch(function (error) { - return orig(error, options); - }); - }; - } - - state.registry[name].push({ - hook: hook, - orig: orig, - }); -} - - -/***/ }), - -/***/ 4670: -/***/ ((module) => { - -module.exports = register; - -function register(state, name, method, options) { - if (typeof method !== "function") { - throw new Error("method for before hook must be a function"); - } - - if (!options) { - options = {}; - } - - if (Array.isArray(name)) { - return name.reverse().reduce(function (callback, name) { - return register.bind(null, state, name, callback, options); - }, method)(); - } - - return Promise.resolve().then(function () { - if (!state.registry[name]) { - return method(options); - } - - return state.registry[name].reduce(function (method, registered) { - return registered.hook.bind(null, method, options); - }, method)(); - }); -} - - -/***/ }), - -/***/ 6819: -/***/ ((module) => { - -module.exports = removeHook; - -function removeHook(state, name, method) { - if (!state.registry[name]) { - return; - } - - var index = state.registry[name] - .map(function (registered) { - return registered.orig; - }) - .indexOf(method); - - if (index === -1) { - return; - } - - state.registry[name].splice(index, 1); -} - - -/***/ }), - -/***/ 1174: -/***/ (function(module) { - -/** - * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. - * https://github.com/SGrondin/bottleneck - */ -(function (global, factory) { - true ? module.exports = factory() : - 0; -}(this, (function () { 'use strict'; - - var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - - function getCjsExportFromNamespace (n) { - return n && n['default'] || n; - } - - var load = function(received, defaults, onto = {}) { - var k, ref, v; - for (k in defaults) { - v = defaults[k]; - onto[k] = (ref = received[k]) != null ? ref : v; - } - return onto; - }; - - var overwrite = function(received, defaults, onto = {}) { - var k, v; - for (k in received) { - v = received[k]; - if (defaults[k] !== void 0) { - onto[k] = v; - } - } - return onto; - }; - - var parser = { - load: load, - overwrite: overwrite - }; - - var DLList; - - DLList = class DLList { - constructor(incr, decr) { - this.incr = incr; - this.decr = decr; - this._first = null; - this._last = null; - this.length = 0; - } - - push(value) { - var node; - this.length++; - if (typeof this.incr === "function") { - this.incr(); - } - node = { - value, - prev: this._last, - next: null - }; - if (this._last != null) { - this._last.next = node; - this._last = node; - } else { - this._first = this._last = node; - } - return void 0; - } - - shift() { - var value; - if (this._first == null) { - return; - } else { - this.length--; - if (typeof this.decr === "function") { - this.decr(); - } - } - value = this._first.value; - if ((this._first = this._first.next) != null) { - this._first.prev = null; - } else { - this._last = null; - } - return value; - } - - first() { - if (this._first != null) { - return this._first.value; - } - } - - getArray() { - var node, ref, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, ref.value)); - } - return results; - } - - forEachShift(cb) { - var node; - node = this.shift(); - while (node != null) { - (cb(node), node = this.shift()); - } - return void 0; - } - - debug() { - var node, ref, ref1, ref2, results; - node = this._first; - results = []; - while (node != null) { - results.push((ref = node, node = node.next, { - value: ref.value, - prev: (ref1 = ref.prev) != null ? ref1.value : void 0, - next: (ref2 = ref.next) != null ? ref2.value : void 0 - })); - } - return results; - } - - }; - - var DLList_1 = DLList; - - var Events; - - Events = class Events { - constructor(instance) { - this.instance = instance; - this._events = {}; - if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { - throw new Error("An Emitter already exists for this object"); - } - this.instance.on = (name, cb) => { - return this._addListener(name, "many", cb); - }; - this.instance.once = (name, cb) => { - return this._addListener(name, "once", cb); - }; - this.instance.removeAllListeners = (name = null) => { - if (name != null) { - return delete this._events[name]; - } else { - return this._events = {}; - } - }; - } - - _addListener(name, status, cb) { - var base; - if ((base = this._events)[name] == null) { - base[name] = []; - } - this._events[name].push({cb, status}); - return this.instance; - } - - listenerCount(name) { - if (this._events[name] != null) { - return this._events[name].length; - } else { - return 0; - } - } - - async trigger(name, ...args) { - var e, promises; - try { - if (name !== "debug") { - this.trigger("debug", `Event triggered: ${name}`, args); - } - if (this._events[name] == null) { - return; - } - this._events[name] = this._events[name].filter(function(listener) { - return listener.status !== "none"; - }); - promises = this._events[name].map(async(listener) => { - var e, returned; - if (listener.status === "none") { - return; - } - if (listener.status === "once") { - listener.status = "none"; - } - try { - returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; - if (typeof (returned != null ? returned.then : void 0) === "function") { - return (await returned); - } else { - return returned; - } - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - }); - return ((await Promise.all(promises))).find(function(x) { - return x != null; - }); - } catch (error) { - e = error; - { - this.trigger("error", e); - } - return null; - } - } - - }; - - var Events_1 = Events; - - var DLList$1, Events$1, Queues; - - DLList$1 = DLList_1; - - Events$1 = Events_1; - - Queues = class Queues { - constructor(num_priorities) { - var i; - this.Events = new Events$1(this); - this._length = 0; - this._lists = (function() { - var j, ref, results; - results = []; - for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { - results.push(new DLList$1((() => { - return this.incr(); - }), (() => { - return this.decr(); - }))); - } - return results; - }).call(this); - } - - incr() { - if (this._length++ === 0) { - return this.Events.trigger("leftzero"); - } - } - - decr() { - if (--this._length === 0) { - return this.Events.trigger("zero"); - } - } - - push(job) { - return this._lists[job.options.priority].push(job); - } - - queued(priority) { - if (priority != null) { - return this._lists[priority].length; - } else { - return this._length; - } - } - - shiftAll(fn) { - return this._lists.forEach(function(list) { - return list.forEachShift(fn); - }); - } - - getFirst(arr = this._lists) { - var j, len, list; - for (j = 0, len = arr.length; j < len; j++) { - list = arr[j]; - if (list.length > 0) { - return list; - } - } - return []; - } - - shiftLastFrom(priority) { - return this.getFirst(this._lists.slice(priority).reverse()).shift(); - } - - }; - - var Queues_1 = Queues; - - var BottleneckError; - - BottleneckError = class BottleneckError extends Error {}; - - var BottleneckError_1 = BottleneckError; - - var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; - - NUM_PRIORITIES = 10; - - DEFAULT_PRIORITY = 5; - - parser$1 = parser; - - BottleneckError$1 = BottleneckError_1; - - Job = class Job { - constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { - this.task = task; - this.args = args; - this.rejectOnDrop = rejectOnDrop; - this.Events = Events; - this._states = _states; - this.Promise = Promise; - this.options = parser$1.load(options, jobDefaults); - this.options.priority = this._sanitizePriority(this.options.priority); - if (this.options.id === jobDefaults.id) { - this.options.id = `${this.options.id}-${this._randomIndex()}`; - } - this.promise = new this.Promise((_resolve, _reject) => { - this._resolve = _resolve; - this._reject = _reject; - }); - this.retryCount = 0; - } - - _sanitizePriority(priority) { - var sProperty; - sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; - if (sProperty < 0) { - return 0; - } else if (sProperty > NUM_PRIORITIES - 1) { - return NUM_PRIORITIES - 1; - } else { - return sProperty; - } - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { - if (this._states.remove(this.options.id)) { - if (this.rejectOnDrop) { - this._reject(error != null ? error : new BottleneckError$1(message)); - } - this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); - return true; - } else { - return false; - } - } - - _assertStatus(expected) { - var status; - status = this._states.jobStatus(this.options.id); - if (!(status === expected || (expected === "DONE" && status === null))) { - throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); - } - } - - doReceive() { - this._states.start(this.options.id); - return this.Events.trigger("received", {args: this.args, options: this.options}); - } - - doQueue(reachedHWM, blocked) { - this._assertStatus("RECEIVED"); - this._states.next(this.options.id); - return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); - } - - doRun() { - if (this.retryCount === 0) { - this._assertStatus("QUEUED"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - return this.Events.trigger("scheduled", {args: this.args, options: this.options}); - } - - async doExecute(chained, clearGlobalState, run, free) { - var error, eventInfo, passed; - if (this.retryCount === 0) { - this._assertStatus("RUNNING"); - this._states.next(this.options.id); - } else { - this._assertStatus("EXECUTING"); - } - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - this.Events.trigger("executing", eventInfo); - try { - passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); - if (clearGlobalState()) { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._resolve(passed); - } - } catch (error1) { - error = error1; - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - } - - doExpire(clearGlobalState, run, free) { - var error, eventInfo; - if (this._states.jobStatus(this.options.id === "RUNNING")) { - this._states.next(this.options.id); - } - this._assertStatus("EXECUTING"); - eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; - error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); - return this._onFailure(error, eventInfo, clearGlobalState, run, free); - } - - async _onFailure(error, eventInfo, clearGlobalState, run, free) { - var retry, retryAfter; - if (clearGlobalState()) { - retry = (await this.Events.trigger("failed", error, eventInfo)); - if (retry != null) { - retryAfter = ~~retry; - this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); - this.retryCount++; - return run(retryAfter); - } else { - this.doDone(eventInfo); - await free(this.options, eventInfo); - this._assertStatus("DONE"); - return this._reject(error); - } - } - } - - doDone(eventInfo) { - this._assertStatus("EXECUTING"); - this._states.next(this.options.id); - return this.Events.trigger("done", eventInfo); - } - - }; - - var Job_1 = Job; - - var BottleneckError$2, LocalDatastore, parser$2; - - parser$2 = parser; - - BottleneckError$2 = BottleneckError_1; - - LocalDatastore = class LocalDatastore { - constructor(instance, storeOptions, storeInstanceOptions) { - this.instance = instance; - this.storeOptions = storeOptions; - this.clientId = this.instance._randomIndex(); - parser$2.load(storeInstanceOptions, storeInstanceOptions, this); - this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); - this._running = 0; - this._done = 0; - this._unblockTime = 0; - this.ready = this.Promise.resolve(); - this.clients = {}; - this._startHeartbeat(); - } - - _startHeartbeat() { - var base; - if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { - return typeof (base = (this.heartbeat = setInterval(() => { - var amount, incr, maximum, now, reservoir; - now = Date.now(); - if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { - this._lastReservoirRefresh = now; - this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; - this.instance._drainAll(this.computeCapacity()); - } - if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { - ({ - reservoirIncreaseAmount: amount, - reservoirIncreaseMaximum: maximum, - reservoir - } = this.storeOptions); - this._lastReservoirIncrease = now; - incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; - if (incr > 0) { - this.storeOptions.reservoir += incr; - return this.instance._drainAll(this.computeCapacity()); - } - } - }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; - } else { - return clearInterval(this.heartbeat); - } - } - - async __publish__(message) { - await this.yieldLoop(); - return this.instance.Events.trigger("message", message.toString()); - } - - async __disconnect__(flush) { - await this.yieldLoop(); - clearInterval(this.heartbeat); - return this.Promise.resolve(); - } - - yieldLoop(t = 0) { - return new this.Promise(function(resolve, reject) { - return setTimeout(resolve, t); - }); - } - - computePenalty() { - var ref; - return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; - } - - async __updateSettings__(options) { - await this.yieldLoop(); - parser$2.overwrite(options, options, this.storeOptions); - this._startHeartbeat(); - this.instance._drainAll(this.computeCapacity()); - return true; - } - - async __running__() { - await this.yieldLoop(); - return this._running; - } - - async __queued__() { - await this.yieldLoop(); - return this.instance.queued(); - } - - async __done__() { - await this.yieldLoop(); - return this._done; - } - - async __groupCheck__(time) { - await this.yieldLoop(); - return (this._nextRequest + this.timeout) < time; - } - - computeCapacity() { - var maxConcurrent, reservoir; - ({maxConcurrent, reservoir} = this.storeOptions); - if ((maxConcurrent != null) && (reservoir != null)) { - return Math.min(maxConcurrent - this._running, reservoir); - } else if (maxConcurrent != null) { - return maxConcurrent - this._running; - } else if (reservoir != null) { - return reservoir; - } else { - return null; - } - } - - conditionsCheck(weight) { - var capacity; - capacity = this.computeCapacity(); - return (capacity == null) || weight <= capacity; - } - - async __incrementReservoir__(incr) { - var reservoir; - await this.yieldLoop(); - reservoir = this.storeOptions.reservoir += incr; - this.instance._drainAll(this.computeCapacity()); - return reservoir; - } - - async __currentReservoir__() { - await this.yieldLoop(); - return this.storeOptions.reservoir; - } - - isBlocked(now) { - return this._unblockTime >= now; - } - - check(weight, now) { - return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; - } - - async __check__(weight) { - var now; - await this.yieldLoop(); - now = Date.now(); - return this.check(weight, now); - } - - async __register__(index, weight, expiration) { - var now, wait; - await this.yieldLoop(); - now = Date.now(); - if (this.conditionsCheck(weight)) { - this._running += weight; - if (this.storeOptions.reservoir != null) { - this.storeOptions.reservoir -= weight; - } - wait = Math.max(this._nextRequest - now, 0); - this._nextRequest = now + wait + this.storeOptions.minTime; - return { - success: true, - wait, - reservoir: this.storeOptions.reservoir - }; - } else { - return { - success: false - }; - } - } - - strategyIsBlock() { - return this.storeOptions.strategy === 3; - } - - async __submit__(queueLength, weight) { - var blocked, now, reachedHWM; - await this.yieldLoop(); - if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { - throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); - } - now = Date.now(); - reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); - blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); - if (blocked) { - this._unblockTime = now + this.computePenalty(); - this._nextRequest = this._unblockTime + this.storeOptions.minTime; - this.instance._dropAllQueued(); - } - return { - reachedHWM, - blocked, - strategy: this.storeOptions.strategy - }; - } - - async __free__(index, weight) { - await this.yieldLoop(); - this._running -= weight; - this._done += weight; - this.instance._drainAll(this.computeCapacity()); - return { - running: this._running - }; - } - - }; - - var LocalDatastore_1 = LocalDatastore; - - var BottleneckError$3, States; - - BottleneckError$3 = BottleneckError_1; - - States = class States { - constructor(status1) { - this.status = status1; - this._jobs = {}; - this.counts = this.status.map(function() { - return 0; - }); - } - - next(id) { - var current, next; - current = this._jobs[id]; - next = current + 1; - if ((current != null) && next < this.status.length) { - this.counts[current]--; - this.counts[next]++; - return this._jobs[id]++; - } else if (current != null) { - this.counts[current]--; - return delete this._jobs[id]; - } - } - - start(id) { - var initial; - initial = 0; - this._jobs[id] = initial; - return this.counts[initial]++; - } - - remove(id) { - var current; - current = this._jobs[id]; - if (current != null) { - this.counts[current]--; - delete this._jobs[id]; - } - return current != null; - } - - jobStatus(id) { - var ref; - return (ref = this.status[this._jobs[id]]) != null ? ref : null; - } - - statusJobs(status) { - var k, pos, ref, results, v; - if (status != null) { - pos = this.status.indexOf(status); - if (pos < 0) { - throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); - } - ref = this._jobs; - results = []; - for (k in ref) { - v = ref[k]; - if (v === pos) { - results.push(k); - } - } - return results; - } else { - return Object.keys(this._jobs); - } - } - - statusCounts() { - return this.counts.reduce(((acc, v, i) => { - acc[this.status[i]] = v; - return acc; - }), {}); - } - - }; - - var States_1 = States; - - var DLList$2, Sync; - - DLList$2 = DLList_1; - - Sync = class Sync { - constructor(name, Promise) { - this.schedule = this.schedule.bind(this); - this.name = name; - this.Promise = Promise; - this._running = 0; - this._queue = new DLList$2(); - } - - isEmpty() { - return this._queue.length === 0; - } - - async _tryToRun() { - var args, cb, error, reject, resolve, returned, task; - if ((this._running < 1) && this._queue.length > 0) { - this._running++; - ({task, args, resolve, reject} = this._queue.shift()); - cb = (await (async function() { - try { - returned = (await task(...args)); - return function() { - return resolve(returned); - }; - } catch (error1) { - error = error1; - return function() { - return reject(error); - }; - } - })()); - this._running--; - this._tryToRun(); - return cb(); - } - } - - schedule(task, ...args) { - var promise, reject, resolve; - resolve = reject = null; - promise = new this.Promise(function(_resolve, _reject) { - resolve = _resolve; - return reject = _reject; - }); - this._queue.push({task, args, resolve, reject}); - this._tryToRun(); - return promise; - } - - }; - - var Sync_1 = Sync; - - var version = "2.19.5"; - var version$1 = { - version: version - }; - - var version$2 = /*#__PURE__*/Object.freeze({ - version: version, - default: version$1 - }); - - var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; - - parser$3 = parser; - - Events$2 = Events_1; - - RedisConnection$1 = require$$2; - - IORedisConnection$1 = require$$3; - - Scripts$1 = require$$4; - - Group = (function() { - class Group { - constructor(limiterOptions = {}) { - this.deleteKey = this.deleteKey.bind(this); - this.limiterOptions = limiterOptions; - parser$3.load(this.limiterOptions, this.defaults, this); - this.Events = new Events$2(this); - this.instances = {}; - this.Bottleneck = Bottleneck_1; - this._startAutoCleanup(); - this.sharedConnection = this.connection != null; - if (this.connection == null) { - if (this.limiterOptions.datastore === "redis") { - this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } else if (this.limiterOptions.datastore === "ioredis") { - this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); - } - } - } - - key(key = "") { - var ref; - return (ref = this.instances[key]) != null ? ref : (() => { - var limiter; - limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { - id: `${this.id}-${key}`, - timeout: this.timeout, - connection: this.connection - })); - this.Events.trigger("created", limiter, key); - return limiter; - })(); - } - - async deleteKey(key = "") { - var deleted, instance; - instance = this.instances[key]; - if (this.connection) { - deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); - } - if (instance != null) { - delete this.instances[key]; - await instance.disconnect(); - } - return (instance != null) || deleted > 0; - } - - limiters() { - var k, ref, results, v; - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - results.push({ - key: k, - limiter: v - }); - } - return results; - } - - keys() { - return Object.keys(this.instances); - } - - async clusterKeys() { - var cursor, end, found, i, k, keys, len, next, start; - if (this.connection == null) { - return this.Promise.resolve(this.keys()); - } - keys = []; - cursor = null; - start = `b_${this.id}-`.length; - end = "_settings".length; - while (cursor !== 0) { - [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); - cursor = ~~next; - for (i = 0, len = found.length; i < len; i++) { - k = found[i]; - keys.push(k.slice(start, -end)); - } - } - return keys; - } - - _startAutoCleanup() { - var base; - clearInterval(this.interval); - return typeof (base = (this.interval = setInterval(async() => { - var e, k, ref, results, time, v; - time = Date.now(); - ref = this.instances; - results = []; - for (k in ref) { - v = ref[k]; - try { - if ((await v._store.__groupCheck__(time))) { - results.push(this.deleteKey(k)); - } else { - results.push(void 0); - } - } catch (error) { - e = error; - results.push(v.Events.trigger("error", e)); - } - } - return results; - }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; - } - - updateSettings(options = {}) { - parser$3.overwrite(options, this.defaults, this); - parser$3.overwrite(options, options, this.limiterOptions); - if (options.timeout != null) { - return this._startAutoCleanup(); - } - } - - disconnect(flush = true) { - var ref; - if (!this.sharedConnection) { - return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; - } - } - - } - Group.prototype.defaults = { - timeout: 1000 * 60 * 5, - connection: null, - Promise: Promise, - id: "group-key" - }; - - return Group; - - }).call(commonjsGlobal); - - var Group_1 = Group; - - var Batcher, Events$3, parser$4; - - parser$4 = parser; - - Events$3 = Events_1; - - Batcher = (function() { - class Batcher { - constructor(options = {}) { - this.options = options; - parser$4.load(this.options, this.defaults, this); - this.Events = new Events$3(this); - this._arr = []; - this._resetPromise(); - this._lastFlush = Date.now(); - } - - _resetPromise() { - return this._promise = new this.Promise((res, rej) => { - return this._resolve = res; - }); - } - - _flush() { - clearTimeout(this._timeout); - this._lastFlush = Date.now(); - this._resolve(); - this.Events.trigger("batch", this._arr); - this._arr = []; - return this._resetPromise(); - } - - add(data) { - var ret; - this._arr.push(data); - ret = this._promise; - if (this._arr.length === this.maxSize) { - this._flush(); - } else if ((this.maxTime != null) && this._arr.length === 1) { - this._timeout = setTimeout(() => { - return this._flush(); - }, this.maxTime); - } - return ret; - } - - } - Batcher.prototype.defaults = { - maxTime: null, - maxSize: null, - Promise: Promise - }; - - return Batcher; - - }).call(commonjsGlobal); - - var Batcher_1 = Batcher; - - var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); - - var require$$8 = getCjsExportFromNamespace(version$2); - - var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, - splice = [].splice; - - NUM_PRIORITIES$1 = 10; - - DEFAULT_PRIORITY$1 = 5; - - parser$5 = parser; - - Queues$1 = Queues_1; - - Job$1 = Job_1; - - LocalDatastore$1 = LocalDatastore_1; - - RedisDatastore$1 = require$$4$1; - - Events$4 = Events_1; - - States$1 = States_1; - - Sync$1 = Sync_1; - - Bottleneck = (function() { - class Bottleneck { - constructor(options = {}, ...invalid) { - var storeInstanceOptions, storeOptions; - this._addToQueue = this._addToQueue.bind(this); - this._validateOptions(options, invalid); - parser$5.load(options, this.instanceDefaults, this); - this._queues = new Queues$1(NUM_PRIORITIES$1); - this._scheduled = {}; - this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); - this._limiter = null; - this.Events = new Events$4(this); - this._submitLock = new Sync$1("submit", this.Promise); - this._registerLock = new Sync$1("register", this.Promise); - storeOptions = parser$5.load(options, this.storeDefaults, {}); - this._store = (function() { - if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { - storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); - return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); - } else if (this.datastore === "local") { - storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); - return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); - } else { - throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); - } - }).call(this); - this._queues.on("leftzero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; - }); - this._queues.on("zero", () => { - var ref; - return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; - }); - } - - _validateOptions(options, invalid) { - if (!((options != null) && typeof options === "object" && invalid.length === 0)) { - throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); - } - } - - ready() { - return this._store.ready; - } - - clients() { - return this._store.clients; - } - - channel() { - return `b_${this.id}`; - } - - channel_client() { - return `b_${this.id}_${this._store.clientId}`; - } - - publish(message) { - return this._store.__publish__(message); - } - - disconnect(flush = true) { - return this._store.__disconnect__(flush); - } - - chain(_limiter) { - this._limiter = _limiter; - return this; - } - - queued(priority) { - return this._queues.queued(priority); - } - - clusterQueued() { - return this._store.__queued__(); - } - - empty() { - return this.queued() === 0 && this._submitLock.isEmpty(); - } - - running() { - return this._store.__running__(); - } - - done() { - return this._store.__done__(); - } - - jobStatus(id) { - return this._states.jobStatus(id); - } - - jobs(status) { - return this._states.statusJobs(status); - } - - counts() { - return this._states.statusCounts(); - } - - _randomIndex() { - return Math.random().toString(36).slice(2); - } - - check(weight = 1) { - return this._store.__check__(weight); - } - - _clearGlobalState(index) { - if (this._scheduled[index] != null) { - clearTimeout(this._scheduled[index].expiration); - delete this._scheduled[index]; - return true; - } else { - return false; - } - } - - async _free(index, job, options, eventInfo) { - var e, running; - try { - ({running} = (await this._store.__free__(index, options.weight))); - this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); - if (running === 0 && this.empty()) { - return this.Events.trigger("idle"); - } - } catch (error1) { - e = error1; - return this.Events.trigger("error", e); - } - } - - _run(index, job, wait) { - var clearGlobalState, free, run; - job.doRun(); - clearGlobalState = this._clearGlobalState.bind(this, index); - run = this._run.bind(this, index, job); - free = this._free.bind(this, index, job); - return this._scheduled[index] = { - timeout: setTimeout(() => { - return job.doExecute(this._limiter, clearGlobalState, run, free); - }, wait), - expiration: job.options.expiration != null ? setTimeout(function() { - return job.doExpire(clearGlobalState, run, free); - }, wait + job.options.expiration) : void 0, - job: job - }; - } - - _drainOne(capacity) { - return this._registerLock.schedule(() => { - var args, index, next, options, queue; - if (this.queued() === 0) { - return this.Promise.resolve(null); - } - queue = this._queues.getFirst(); - ({options, args} = next = queue.first()); - if ((capacity != null) && options.weight > capacity) { - return this.Promise.resolve(null); - } - this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); - index = this._randomIndex(); - return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { - var empty; - this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); - if (success) { - queue.shift(); - empty = this.empty(); - if (empty) { - this.Events.trigger("empty"); - } - if (reservoir === 0) { - this.Events.trigger("depleted", empty); - } - this._run(index, next, wait); - return this.Promise.resolve(options.weight); - } else { - return this.Promise.resolve(null); - } - }); - }); - } - - _drainAll(capacity, total = 0) { - return this._drainOne(capacity).then((drained) => { - var newCapacity; - if (drained != null) { - newCapacity = capacity != null ? capacity - drained : capacity; - return this._drainAll(newCapacity, total + drained); - } else { - return this.Promise.resolve(total); - } - }).catch((e) => { - return this.Events.trigger("error", e); - }); - } - - _dropAllQueued(message) { - return this._queues.shiftAll(function(job) { - return job.doDrop({message}); - }); - } - - stop(options = {}) { - var done, waitForExecuting; - options = parser$5.load(options, this.stopDefaults); - waitForExecuting = (at) => { - var finished; - finished = () => { - var counts; - counts = this._states.counts; - return (counts[0] + counts[1] + counts[2] + counts[3]) === at; - }; - return new this.Promise((resolve, reject) => { - if (finished()) { - return resolve(); - } else { - return this.on("done", () => { - if (finished()) { - this.removeAllListeners("done"); - return resolve(); - } - }); - } - }); - }; - done = options.dropWaitingJobs ? (this._run = function(index, next) { - return next.doDrop({ - message: options.dropErrorMessage - }); - }, this._drainOne = () => { - return this.Promise.resolve(null); - }, this._registerLock.schedule(() => { - return this._submitLock.schedule(() => { - var k, ref, v; - ref = this._scheduled; - for (k in ref) { - v = ref[k]; - if (this.jobStatus(v.job.options.id) === "RUNNING") { - clearTimeout(v.timeout); - clearTimeout(v.expiration); - v.job.doDrop({ - message: options.dropErrorMessage - }); - } - } - this._dropAllQueued(options.dropErrorMessage); - return waitForExecuting(0); - }); - })) : this.schedule({ - priority: NUM_PRIORITIES$1 - 1, - weight: 0 - }, () => { - return waitForExecuting(1); - }); - this._receive = function(job) { - return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); - }; - this.stop = () => { - return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); - }; - return done; - } - - async _addToQueue(job) { - var args, blocked, error, options, reachedHWM, shifted, strategy; - ({args, options} = job); - try { - ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); - } catch (error1) { - error = error1; - this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); - job.doDrop({error}); - return false; - } - if (blocked) { - job.doDrop(); - return true; - } else if (reachedHWM) { - shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; - if (shifted != null) { - shifted.doDrop(); - } - if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { - if (shifted == null) { - job.doDrop(); - } - return reachedHWM; - } - } - job.doQueue(reachedHWM, blocked); - this._queues.push(job); - await this._drainAll(); - return reachedHWM; - } - - _receive(job) { - if (this._states.jobStatus(job.options.id) != null) { - job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); - return false; - } else { - job.doReceive(); - return this._submitLock.schedule(this._addToQueue, job); - } - } - - submit(...args) { - var cb, fn, job, options, ref, ref1, task; - if (typeof args[0] === "function") { - ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); - options = parser$5.load({}, this.jobDefaults); - } else { - ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); - options = parser$5.load(options, this.jobDefaults); - } - task = (...args) => { - return new this.Promise(function(resolve, reject) { - return fn(...args, function(...args) { - return (args[0] != null ? reject : resolve)(args); - }); - }); - }; - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - job.promise.then(function(args) { - return typeof cb === "function" ? cb(...args) : void 0; - }).catch(function(args) { - if (Array.isArray(args)) { - return typeof cb === "function" ? cb(...args) : void 0; - } else { - return typeof cb === "function" ? cb(args) : void 0; - } - }); - return this._receive(job); - } - - schedule(...args) { - var job, options, task; - if (typeof args[0] === "function") { - [task, ...args] = args; - options = {}; - } else { - [options, task, ...args] = args; - } - job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); - this._receive(job); - return job.promise; - } - - wrap(fn) { - var schedule, wrapped; - schedule = this.schedule.bind(this); - wrapped = function(...args) { - return schedule(fn.bind(this), ...args); - }; - wrapped.withOptions = function(options, ...args) { - return schedule(options, fn, ...args); - }; - return wrapped; - } - - async updateSettings(options = {}) { - await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); - parser$5.overwrite(options, this.instanceDefaults, this); - return this; - } - - currentReservoir() { - return this._store.__currentReservoir__(); - } - - incrementReservoir(incr = 0) { - return this._store.__incrementReservoir__(incr); - } - - } - Bottleneck.default = Bottleneck; - - Bottleneck.Events = Events$4; - - Bottleneck.version = Bottleneck.prototype.version = require$$8.version; - - Bottleneck.strategy = Bottleneck.prototype.strategy = { - LEAK: 1, - OVERFLOW: 2, - OVERFLOW_PRIORITY: 4, - BLOCK: 3 - }; - - Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; - - Bottleneck.Group = Bottleneck.prototype.Group = Group_1; - - Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; - - Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; - - Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; - - Bottleneck.prototype.jobDefaults = { - priority: DEFAULT_PRIORITY$1, - weight: 1, - expiration: null, - id: "" - }; - - Bottleneck.prototype.storeDefaults = { - maxConcurrent: null, - minTime: 0, - highWater: null, - strategy: Bottleneck.prototype.strategy.LEAK, - penalty: null, - reservoir: null, - reservoirRefreshInterval: null, - reservoirRefreshAmount: null, - reservoirIncreaseInterval: null, - reservoirIncreaseAmount: null, - reservoirIncreaseMaximum: null - }; + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; - Bottleneck.prototype.localStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 250 - }; +const VERSION = "5.16.2"; - Bottleneck.prototype.redisStoreDefaults = { - Promise: Promise, - timeout: null, - heartbeatInterval: 5000, - clientTimeout: 10000, - Redis: null, - clientOptions: {}, - clusterNodes: null, - clearDatastore: false, - connection: null - }; +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; - Bottleneck.prototype.instanceDefaults = { - datastore: "local", - connection: null, - id: "", - rejectOnDrop: true, - trackDoneStatus: false, - Promise: Promise - }; + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); - Bottleneck.prototype.stopDefaults = { - enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", - dropWaitingJobs: true, - dropErrorMessage: "This limiter has been stopped." - }; + if (!newMethods[scope]) { + newMethods[scope] = {}; + } - return Bottleneck; + const scopeMethods = newMethods[scope]; - }).call(commonjsGlobal); + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } - var Bottleneck_1 = Bottleneck; + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); + } + } - var lib = Bottleneck_1; + return newMethods; +} - return lib; +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ -}))); + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } -/***/ }), + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } -"use strict"; + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); -Object.defineProperty(exports, "__esModule", ({ value: true })); + if (!(alias in options)) { + options[alias] = options[name]; + } -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) + delete options[name]; + } + } - /* istanbul ignore next */ + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - this.name = 'Deprecation'; + return requestWithDefaults(...args); } + return Object.assign(withDecorations, requestWithDefaults); } -exports.Deprecation = Deprecation; - - -/***/ }), - -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); } +legacyRestEndpointMethods.VERSION = VERSION; -function isPlainObject(o) { - var ctor,prot; +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map - if (isObject(o) === false) return false; - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; +/***/ }), - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; +/***/ 9968: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; - } +"use strict"; - // Most likely a plain Object - return true; -} -exports.isPlainObject = isPlainObject; +Object.defineProperty(exports, "__esModule", ({ value: true })); +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -/***/ }), +var BottleneckLight = _interopDefault(__nccwpck_require__(1174)); -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const VERSION = "4.1.0"; -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); +const noop = () => Promise.resolve(); // @ts-expect-error -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} +function wrapRequest(state, request, options) { + return state.retryLimiter.schedule(doRequest, state, request, options); +} // @ts-expect-error -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; +async function doRequest(state, request, options) { + const isWrite = options.method !== "GET" && options.method !== "HEAD"; + const { + pathname + } = new URL(options.url, "http://github.test"); + const isSearch = options.method === "GET" && pathname.startsWith("/search/"); + const isGraphQL = pathname.startsWith("/graphql"); + const retryCount = ~~options.request.retryCount; + const jobOptions = retryCount > 0 ? { + priority: 0, + weight: 0 + } : {}; -module.exports = Hash; + if (state.clustering) { + // Remove a job from Redis if it has not completed or failed within 60s + // Examples: Node process terminated, client disconnected, etc. + // @ts-expect-error + jobOptions.expiration = 1000 * 60; + } // Guarantee at least 1000ms between writes + // GraphQL can also trigger writes -/***/ }), + if (isWrite || isGraphQL) { + await state.write.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 3000ms between requests that trigger notifications -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); + if (isWrite && state.triggersNotification(pathname)) { + await state.notifications.key(state.id).schedule(jobOptions, noop); + } // Guarantee at least 2000ms between search requests -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (isSearch) { + await state.search.key(state.id).schedule(jobOptions, noop); } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - -/***/ }), + const req = state.global.key(state.id).schedule(jobOptions, request, options); -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (isGraphQL) { + const res = await req; -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); + if (res.data.errors != null && // @ts-expect-error + res.data.errors.some(error => error.type === "RATE_LIMITED")) { + const error = Object.assign(new Error("GraphQL Rate Limit Exceeded"), { + response: res, + data: res.data + }); + throw error; + } + } -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); + return req; +} -module.exports = Map; +var triggersNotificationPaths = ["/orgs/{org}/invitations", "/orgs/{org}/invitations/{invitation_id}", "/orgs/{org}/teams/{team_slug}/discussions", "/orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "/repos/{owner}/{repo}/collaborators/{username}", "/repos/{owner}/{repo}/commits/{commit_sha}/comments", "/repos/{owner}/{repo}/issues", "/repos/{owner}/{repo}/issues/{issue_number}/comments", "/repos/{owner}/{repo}/pulls", "/repos/{owner}/{repo}/pulls/{pull_number}/comments", "/repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies", "/repos/{owner}/{repo}/pulls/{pull_number}/merge", "/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "/repos/{owner}/{repo}/pulls/{pull_number}/reviews", "/repos/{owner}/{repo}/releases", "/teams/{team_id}/discussions", "/teams/{team_id}/discussions/{discussion_number}/comments"]; +function routeMatcher(paths) { + // EXAMPLE. For the following paths: -/***/ }), + /* [ + "/orgs/{org}/invitations", + "/repos/{owner}/{repo}/collaborators/{username}" + ] */ + const regexes = paths.map(path => path.split("/").map(c => c.startsWith("{") ? "(?:.+?)" : c).join("/")); // 'regexes' would contain: -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* [ + '/orgs/(?:.+?)/invitations', + '/repos/(?:.+?)/(?:.+?)/collaborators/(?:.+?)' + ] */ -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); + const regex = `^(?:${regexes.map(r => `(?:${r})`).join("|")})[^/]*$`; // 'regex' would contain: -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; + /* + ^(?:(?:\/orgs\/(?:.+?)\/invitations)|(?:\/repos\/(?:.+?)\/(?:.+?)\/collaborators\/(?:.+?)))[^\/]*$ + It may look scary, but paste it into https://www.debuggex.com/ + and it will make a lot more sense! + */ - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } + return new RegExp(regex, "i"); } -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; +// @ts-expect-error -module.exports = MapCache; +const regex = routeMatcher(triggersNotificationPaths); +const triggersNotification = regex.test.bind(regex); +const groups = {}; // @ts-expect-error +const createGroups = function (Bottleneck, common) { + groups.global = new Bottleneck.Group({ + id: "octokit-global", + maxConcurrent: 10, + ...common + }); + groups.search = new Bottleneck.Group({ + id: "octokit-search", + maxConcurrent: 1, + minTime: 2000, + ...common + }); + groups.write = new Bottleneck.Group({ + id: "octokit-write", + maxConcurrent: 1, + minTime: 1000, + ...common + }); + groups.notifications = new Bottleneck.Group({ + id: "octokit-notifications", + maxConcurrent: 1, + minTime: 3000, + ...common + }); +}; -/***/ }), +function throttling(octokit, octokitOptions) { + const { + enabled = true, + Bottleneck = BottleneckLight, + id = "no-id", + timeout = 1000 * 60 * 2, + // Redis TTL: 2 minutes + connection + } = octokitOptions.throttle || {}; -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!enabled) { + return {}; + } -var root = __nccwpck_require__(9882); + const common = { + connection, + timeout + }; -/** Built-in value references. */ -var Symbol = root.Symbol; + if (groups.global == null) { + createGroups(Bottleneck, common); + } -module.exports = Symbol; + const state = Object.assign({ + clustering: connection != null, + triggersNotification, + minimumSecondaryRateRetryAfter: 5, + retryAfterBaseValue: 1000, + retryLimiter: new Bottleneck(), + id, + ...groups + }, octokitOptions.throttle); + const isUsingDeprecatedOnAbuseLimitHandler = typeof state.onAbuseLimit === "function" && state.onAbuseLimit; + if (typeof (isUsingDeprecatedOnAbuseLimitHandler ? state.onAbuseLimit : state.onSecondaryRateLimit) !== "function" || typeof state.onRateLimit !== "function") { + throw new Error(`octokit/plugin-throttling error: + You must pass the onSecondaryRateLimit and onRateLimit error handlers. + See https://github.com/octokit/rest.js#throttling -/***/ }), + const octokit = new Octokit({ + throttle: { + onSecondaryRateLimit: (retryAfter, options) => {/* ... */}, + onRateLimit: (retryAfter, options) => {/* ... */} + } + }) + `); + } -/***/ 4356: -/***/ ((module) => { + const events = {}; + const emitter = new Bottleneck.Events(events); // @ts-expect-error -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + events.on("secondary-limit", isUsingDeprecatedOnAbuseLimitHandler ? function (...args) { + octokit.log.warn("[@octokit/plugin-throttling] `onAbuseLimit()` is deprecated and will be removed in a future release of `@octokit/plugin-throttling`, please use the `onSecondaryRateLimit` handler instead"); + return state.onAbuseLimit(...args); + } : state.onSecondaryRateLimit); // @ts-expect-error - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; -} + events.on("rate-limit", state.onRateLimit); // @ts-expect-error -module.exports = arrayMap; + events.on("error", e => octokit.log.warn("Error in throttling-plugin limit handler", e)); // @ts-expect-error + state.retryLimiter.on("failed", async function (error, info) { + const options = info.args[info.args.length - 1]; + const { + pathname + } = new URL(options.url, "http://github.test"); + const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; -/***/ }), + if (!(shouldRetryGraphQL || error.status === 403)) { + return; + } -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const retryCount = ~~options.request.retryCount; + options.request.retryCount = retryCount; + const { + wantRetry, + retryAfter = 0 + } = await async function () { + if (/\bsecondary rate\b/i.test(error.message)) { + // The user has hit the secondary rate limit. (REST and GraphQL) + // https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits + // The Retry-After header can sometimes be blank when hitting a secondary rate limit, + // but is always present after 2-3s, so make sure to set `retryAfter` to at least 5s by default. + const retryAfter = Math.max(~~error.response.headers["retry-after"], state.minimumSecondaryRateRetryAfter); + const wantRetry = await emitter.trigger("secondary-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -var eq = __nccwpck_require__(1901); + if (error.response.headers != null && error.response.headers["x-ratelimit-remaining"] === "0") { + // The user has used all their allowed calls for the current time period (REST and GraphQL) + // https://docs.github.com/en/rest/reference/rate-limit (REST) + // https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit (GraphQL) + const rateLimitReset = new Date(~~error.response.headers["x-ratelimit-reset"] * 1000).getTime(); + const retryAfter = Math.max(Math.ceil((rateLimitReset - Date.now()) / 1000), 0); + const wantRetry = await emitter.trigger("rate-limit", retryAfter, options, octokit); + return { + wantRetry, + retryAfter + }; + } -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; + return {}; + }(); + + if (wantRetry) { + options.request.retryCount++; + return retryAfter * state.retryAfterBaseValue; } - } - return -1; + }); + octokit.hook.wrap("request", wrapRequest.bind(null, state)); + return {}; } +throttling.VERSION = VERSION; +throttling.triggersNotification = triggersNotification; -module.exports = assocIndexOf; +exports.throttling = throttling; +//# sourceMappingURL=index.js.map /***/ }), -/***/ 5758: +/***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); +var register = __nccwpck_require__(4670) +var addHook = __nccwpck_require__(5549) +var removeHook = __nccwpck_require__(6819) -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = castPath(path, object); +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind +var bindable = bind.bind(bind) - var index = 0, - length = path.length; +function bindApi (hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) + hook.api = { remove: removeHookRef } + hook.remove = removeHookRef - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; + ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind] + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) + }) } -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function HookSingular () { + var singularHookName = 'h' + var singularHookState = { + registry: {} } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); + var singularHook = register.bind(null, singularHookState, singularHookName) + bindApi(singularHook, singularHookState, singularHookName) + return singularHook } -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +function HookCollection () { + var state = { + registry: {} + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + var hook = register.bind(null, state) + bindApi(hook, state) -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + return hook +} -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; +var collectionHookDeprecationMessageDisplayed = false +function Hook () { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') + collectionHookDeprecationMessageDisplayed = true } - var pattern = isFunction(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); + return HookCollection() } -module.exports = baseIsNative; +Hook.Singular = HookSingular.bind() +Hook.Collection = HookCollection.bind() +module.exports = Hook +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook +module.exports.Singular = Hook.Singular +module.exports.Collection = Hook.Collection -/***/ }), -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ }), -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); +/***/ 5549: +/***/ ((module) => { -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +module.exports = addHook; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} -module.exports = baseToString; + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} /***/ }), -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4670: +/***/ ((module) => { -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); +module.exports = register; -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray(value)) { - return value; +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); } - return isKey(value, object) ? [value] : stringToPath(toString(value)); -} - -module.exports = castPath; - - -/***/ }), -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!options) { + options = {}; + } -var root = __nccwpck_require__(9882); + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } -module.exports = coreJsData; + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} /***/ }), -/***/ 2085: +/***/ 6819: /***/ ((module) => { -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -module.exports = getMapData; - +module.exports = removeHook; -/***/ }), +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); + if (index === -1) { + return; + } -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; + state.registry[name].splice(index, 1); } -module.exports = getNative; - /***/ }), -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +/***/ 1174: +/***/ (function(module) { /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. + * https://github.com/SGrondin/bottleneck + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag), - tag = value[symToStringTag]; + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; -} + function getCjsExportFromNamespace (n) { + return n && n['default'] || n; + } -module.exports = getRawTag; + var load = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; -/***/ }), + var parser = { + load: load, + overwrite: overwrite + }; -/***/ 3542: -/***/ ((module) => { + var DLList; -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } -module.exports = getValue; + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } -/***/ }), + first() { + if (this._first != null) { + return this._first.value; + } + } -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } -var nativeCreate = __nccwpck_require__(3041); + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + (cb(node), node = this.shift()); + } + return void 0; + } -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } -module.exports = hashClear; + }; + var DLList_1 = DLList; -/***/ }), + var Events; -/***/ 712: -/***/ ((module) => { + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({cb, status}); + return this.instance; + } -module.exports = hashDelete; + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async(listener) => { + var e, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return (await returned); + } else { + return returned; + } + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + }); + return ((await Promise.all(promises))).find(function(x) { + return x != null; + }); + } catch (error) { + e = error; + { + this.trigger("error", e); + } + return null; + } + } -/***/ }), + }; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var Events_1 = Events; -var nativeCreate = __nccwpck_require__(3041); + var DLList$1, Events$1, Queues; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DLList$1 = DLList_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Events$1 = Events_1; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } -module.exports = hashGet; + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } -/***/ }), + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } -var nativeCreate = __nccwpck_require__(3041); + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } -/** Used for built-in method references. */ -var objectProto = Object.prototype; + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + }; -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); -} + var Queues_1 = Queues; -module.exports = hashHas; + var BottleneckError; + BottleneckError = class BottleneckError extends Error {}; -/***/ }), + var BottleneckError_1 = BottleneckError; -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; -var nativeCreate = __nccwpck_require__(3041); + NUM_PRIORITIES = 10; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; + DEFAULT_PRIORITY = 5; -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} + parser$1 = parser; -module.exports = hashSet; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events; + this._states = _states; + this.Promise = Promise; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } -/***/ }), + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + _randomIndex() { + return Math.random().toString(36).slice(2); + } -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); + doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error != null ? error : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); + return true; + } else { + return false; + } + } -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || (expected === "DONE" && status === null))) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); -} + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", {args: this.args, options: this.options}); + } -module.exports = isKey; + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", {args: this.args, options: this.options}); + } -/***/ }), + async doExecute(chained, clearGlobalState, run, free) { + var error, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + this.Events.trigger("executing", eventInfo); + try { + passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error = error1; + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } + } -/***/ 3308: -/***/ ((module) => { + doExpire(clearGlobalState, run, free) { + var error, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; + error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error, eventInfo, clearGlobalState, run, free); + } -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} + async _onFailure(error, eventInfo, clearGlobalState, run, free) { + var retry, retryAfter; + if (clearGlobalState()) { + retry = (await this.Events.trigger("failed", error, eventInfo)); + if (retry != null) { + retryAfter = ~~retry; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error); + } + } + } -module.exports = isKeyable; + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; -/***/ }), + var Job_1 = Job; -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var BottleneckError$2, LocalDatastore, parser$2; -var coreJsData = __nccwpck_require__(8380); + parser$2 = parser; -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); + BottleneckError$2 = BottleneckError_1; -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } -module.exports = isMasked; + _startHeartbeat() { + var base; + if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { + return typeof (base = (this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } -/***/ }), + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } -/***/ 9792: -/***/ ((module) => { + yieldLoop(t = 0) { + return new this.Promise(function(resolve, reject) { + return setTimeout(resolve, t); + }); + } -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; -} + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; + } -module.exports = listCacheClear; + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } -/***/ }), + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __done__() { + await this.yieldLoop(); + return this._done; + } -var assocIndexOf = __nccwpck_require__(6752); + async __groupCheck__(time) { + await this.yieldLoop(); + return (this._nextRequest + this.timeout) < time; + } -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + computeCapacity() { + var maxConcurrent, reservoir; + ({maxConcurrent, reservoir} = this.storeOptions); + if ((maxConcurrent != null) && (reservoir != null)) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } -/** Built-in value references. */ -var splice = arrayProto.splice; + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return (capacity == null) || weight <= capacity; + } -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } -module.exports = listCacheDelete; + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; + } -/***/ }), + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } -var assocIndexOf = __nccwpck_require__(6752); + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } - return index < 0 ? undefined : data[index][1]; -} + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } -module.exports = listCacheGet; + }; + var LocalDatastore_1 = LocalDatastore; -/***/ }), + var BottleneckError$3, States; -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + BottleneckError$3 = BottleneckError_1; -var assocIndexOf = __nccwpck_require__(6752); + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if ((current != null) && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } -module.exports = listCacheHas; + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } -/***/ }), + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } -var assocIndexOf = __nccwpck_require__(6752); + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); + }; - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} + var States_1 = States; -module.exports = listCacheSet; + var DLList$2, Sync; + DLList$2 = DLList_1; -/***/ }), + Sync = class Sync { + constructor(name, Promise) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise; + this._running = 0; + this._queue = new DLList$2(); + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + isEmpty() { + return this._queue.length === 0; + } -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); + async _tryToRun() { + var args, cb, error, reject, resolve, returned, task; + if ((this._running < 1) && this._queue.length > 0) { + this._running++; + ({task, args, resolve, reject} = this._queue.shift()); + cb = (await (async function() { + try { + returned = (await task(...args)); + return function() { + return resolve(returned); + }; + } catch (error1) { + error = error1; + return function() { + return reject(error); + }; + } + })()); + this._running--; + this._tryToRun(); + return cb(); + } + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} + schedule(task, ...args) { + var promise, reject, resolve; + resolve = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve = _resolve; + return reject = _reject; + }); + this._queue.push({task, args, resolve, reject}); + this._tryToRun(); + return promise; + } -module.exports = mapCacheClear; + }; + var Sync_1 = Sync; -/***/ }), + var version = "2.19.5"; + var version$1 = { + version: version + }; -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var version$2 = /*#__PURE__*/Object.freeze({ + version: version, + default: version$1 + }); -var getMapData = __nccwpck_require__(9980); + var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -module.exports = mapCacheDelete; + var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; -/***/ }), + parser$3 = parser; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Events$2 = Events_1; -var getMapData = __nccwpck_require__(9980); + RedisConnection$1 = require$$2; -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} + IORedisConnection$1 = require$$3; -module.exports = mapCacheGet; + Scripts$1 = require$$4; + Group = (function() { + class Group { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); + } + } + } -/***/ }), + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return (instance != null) || deleted > 0; + } -var getMapData = __nccwpck_require__(9980); + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} + keys() { + return Object.keys(this.instances); + } + + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } -module.exports = mapCacheHas; + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = (this.interval = setInterval(async() => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if ((await v._store.__groupCheck__(time))) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error) { + e = error; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } -/***/ }), + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } -/***/ 5582: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Group.prototype.defaults = { + timeout: 1000 * 60 * 5, + connection: null, + Promise: Promise, + id: "group-key" + }; -var getMapData = __nccwpck_require__(9980); + return Group; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = getMapData(this, key), - size = data.size; + }).call(commonjsGlobal); - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + var Group_1 = Group; -module.exports = mapCacheSet; + var Batcher, Events$3, parser$4; + parser$4 = parser; -/***/ }), + Events$3 = Events_1; -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Batcher = (function() { + class Batcher { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } -var memoize = __nccwpck_require__(9885); + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if ((this.maxTime != null) && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } - var cache = result.cache; - return result; -} + } + Batcher.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise: Promise + }; -module.exports = memoizeCapped; + return Batcher; + }).call(commonjsGlobal); -/***/ }), + var Batcher_1 = Batcher; -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); -var getNative = __nccwpck_require__(4479); + var require$$8 = getCjsExportFromNamespace(version$2); -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, + splice = [].splice; -module.exports = nativeCreate; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; -/***/ }), + parser$5 = parser; -/***/ 4200: -/***/ ((module) => { + Queues$1 = Queues_1; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + Job$1 = Job_1; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + LocalDatastore$1 = LocalDatastore_1; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + RedisDatastore$1 = require$$4$1; -module.exports = objectToString; + Events$4 = Events_1; + States$1 = States_1; -/***/ }), + Sync$1 = Sync_1; -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck = (function() { + class Bottleneck { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } -var freeGlobal = __nccwpck_require__(2085); + _validateOptions(options, invalid) { + if (!((options != null) && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + ready() { + return this._store.ready; + } -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); + clients() { + return this._store.clients; + } -module.exports = root; + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } -/***/ }), + publish(message) { + return this._store.__publish__(message); + } -/***/ 1853: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } -var memoizeCapped = __nccwpck_require__(9422); + chain(_limiter) { + this._limiter = _limiter; + return this; + } -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + queued(priority) { + return this._queues.queued(priority); + } -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + clusterQueued() { + return this._store.__queued__(); + } -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } -module.exports = stringToPath; + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } -/***/ }), + jobStatus(id) { + return this._states.jobStatus(id); + } -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + jobs(status) { + return this._states.statusJobs(status); + } -var isSymbol = __nccwpck_require__(6403); + counts() { + return this._states.statusCounts(); + } -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + _randomIndex() { + return Math.random().toString(36).slice(2); + } -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; -} + check(weight = 1) { + return this._store.__check__(weight); + } -module.exports = toKey; + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({running} = (await this._store.__free__(index, options.weight))); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } -/***/ }), + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job: job + }; + } -/***/ 6928: -/***/ ((module) => { + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({options, args} = next = queue.first()); + if ((capacity != null) && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } -/** Used for built-in method references. */ -var funcProto = Function.prototype; + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({message}); + }); + } -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return (counts[0] + counts[1] + counts[2] + counts[3]) === at; + }; + return new this.Promise((resolve, reject) => { + if (finished()) { + return resolve(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } -module.exports = toSource; + async _addToQueue(job) { + var args, blocked, error, options, reachedHWM, shifted, strategy; + ({args, options} = job); + try { + ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); + } catch (error1) { + error = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); + job.doDrop({error}); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } -/***/ }), + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args) => { + return new this.Promise(function(resolve, reject) { + return fn(...args, function(...args) { + return (args[0] != null ? reject : resolve)(args); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args) { + return typeof cb === "function" ? cb(...args) : void 0; + }).catch(function(args) { + if (Array.isArray(args)) { + return typeof cb === "function" ? cb(...args) : void 0; + } else { + return typeof cb === "function" ? cb(args) : void 0; + } + }); + return this._receive(job); + } -/***/ 1901: -/***/ ((module) => { + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } -module.exports = eq; + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } -/***/ }), + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + } + Bottleneck.default = Bottleneck; -var baseGet = __nccwpck_require__(5758); + Bottleneck.Events = Events$4; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; -} + Bottleneck.version = Bottleneck.prototype.version = require$$8.version; -module.exports = get; + Bottleneck.strategy = Bottleneck.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; -/***/ }), + Bottleneck.Group = Bottleneck.prototype.Group = Group_1; -/***/ 4869: -/***/ ((module) => { + Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; -module.exports = isArray; + Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; + Bottleneck.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; -/***/ }), + Bottleneck.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + Bottleneck.prototype.localStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 250 + }; -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); + Bottleneck.prototype.redisStoreDefaults = { + Promise: Promise, + timeout: null, + heartbeatInterval: 5000, + clientTimeout: 10000, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; + Bottleneck.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise: Promise + }; -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; -} + Bottleneck.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; -module.exports = isFunction; + return Bottleneck; + }).call(commonjsGlobal); -/***/ }), + var Bottleneck_1 = Bottleneck; -/***/ 3334: -/***/ ((module) => { + var lib = Bottleneck_1; -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} + return lib; -module.exports = isObject; +}))); /***/ }), -/***/ 5926: -/***/ ((module) => { +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} +"use strict"; -module.exports = isObjectLike; +Object.defineProperty(exports, "__esModule", ({ value: true })); -/***/ }), +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /* istanbul ignore next */ -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; + this.name = 'Deprecation'; + } -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); } -module.exports = isSymbol; +exports.Deprecation = Deprecation; /***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { -var MapCache = __nccwpck_require__(938); +"use strict"; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; +function isPlainObject(o) { + var ctor,prot; + if (isObject(o) === false) return false; -/***/ }), + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; -var baseToString = __nccwpck_require__(6792); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : baseToString(value); + // Most likely a plain Object + return true; } -module.exports = toString; +exports.isPlainObject = isPlainObject; /***/ }), @@ -13417,230 +11261,716 @@ var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - const bytes = []; + return wrapper - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } - - return bytes; } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); +/***/ }), + +/***/ 9296: +/***/ (function(module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.POLL_RATE = exports.ISSUE_OR_PULL_REQUEST_REGEX = void 0; +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +const core = __importStar(__nccwpck_require__(2186)); +const utils_1 = __nccwpck_require__(3030); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +const plugin_throttling_1 = __nccwpck_require__(9968); +const EmptyObject_1 = __nccwpck_require__(8227); +const arrayDifference_1 = __importDefault(__nccwpck_require__(7034)); +const CONST_1 = __importDefault(__nccwpck_require__(4097)); +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); +exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; +exports.POLL_RATE = POLL_RATE; +class GithubUtils { + static internalOctokit; + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_paginate_rest_1.paginateRest); + const token = core.getInput('GITHUB_TOKEN', { required: true }); + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit((0, utils_1.getOctokitOptions)(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter, options) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter, options) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + })); + } + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.rest; + } + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.graphql; + } + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate() { + if (!this.internalOctokit) { + this.initOctokit(); + } + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return this.internalOctokit.paginate; + } + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash() { + return this.octokit.issues + .listForRepo({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + labels: CONST_1.default.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({ data }) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + if (data.length > 1) { + throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(data[0]); + }); + } + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue) { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } + catch (exception) { + throw new Error(`Unable to find ${CONST_1.default.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue) { + let PRListSection = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + return PRList.sort((a, b) => a.number - b.number); + } + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue) { + let deployBlockerSection = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return deployBlockers.sort((a, b) => a.number - b.number); + } + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue) { + let internalQASection = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + return internalQAPRs.sort((a, b) => a.number - b.number); + } + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees(tag, PRList, verifiedPRList = [], deployBlockers = [], resolvedDeployBlockers = [], resolvedInternalQAPRs = [], isTimingDashboardChecked = false, isFirebaseChecked = false, isGHStatusChecked = false) { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !(0, EmptyObject_1.isEmptyObject)(pr.labels.find((item) => item.name === CONST_1.default.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({ url: pr.html_url, mergerLogin })))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce((acc, { url, mergerLogin }) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + const sortedPRList = [...new Set((0, arrayDifference_1.default)(PRList, Object.keys(internalQAPRMap)))].sort((a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b)); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort((a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b)); + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + // Internal QA PR list + if (!(0, EmptyObject_1.isEmptyObject)(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isTimingDashboardChecked ? 'x' : ' '}] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isFirebaseChecked ? 'x' : ' '}] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = { issueBody, issueAssignees }; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers) { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate(this.octokit.pulls.list, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, ({ data }, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + static getPullRequestMergerLogin(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequest }) => pullRequest.merged_by?.login); + } + static getPullRequestBody(pullRequestNumber) { + return this.octokit.pulls + .get({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({ data: pullRequestComment }) => pullRequestComment.body); + } + static getAllReviewComments(pullRequestNumber) { + return this.paginate(this.octokit.pulls.listReviews, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, (response) => response.data.map((review) => review.body)); + } + static getAllComments(issueNumber) { + return this.paginate(this.octokit.issues.listComments, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, (response) => response.data.map((comment) => comment.body)); + } + /** + * Create comment on pull request + */ + static createComment(repo, number, messageBody) { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST_1.default.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); } - - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow) { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); } - - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - - - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; - } - - return buf; + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests) { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); } - - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support - - - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} - -/***/ }), - -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function v4(options, buf, offset) { - options = options || {}; - - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value) { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST_1.default.APP_REPO_URL}/pull/${value}`; + } + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL) { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL) { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL) { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber) { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + static getArtifactByName(artefactName) { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST_1.default.GITHUB_OWNER, + repo: CONST_1.default.APP_REPO, + per_page: 100, + }).then((artifacts) => artifacts.find((artifact) => artifact.name === artefactName)); } - - return buf; - } - - return (0, _stringify.default)(rnds); } +exports["default"] = GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; -var _default = v4; -exports["default"] = _default; - -/***/ }), - -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _v = _interopRequireDefault(__nccwpck_require__(5998)); - -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; /***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 8227: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _regex = _interopRequireDefault(__nccwpck_require__(814)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.isEmptyObject = void 0; +function isEmptyObject(obj) { + return Object.keys(obj ?? {}).length === 0; } +exports.isEmptyObject = isEmptyObject; -var _default = validate; -exports["default"] = _default; /***/ }), -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 7034: +/***/ ((__unused_webpack_module, exports) => { "use strict"; - -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); - } - - return parseInt(uuid.substr(14, 1), 16); -} - -var _default = version; -exports["default"] = _default; - -/***/ }), - -/***/ 2940: -/***/ ((module) => { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +/** + * This function is an equivalent of _.difference, it takes two arrays and returns the difference between them. + * It returns an array of items that are in the first array but not in the second array. + */ +function arrayDifference(array1, array2) { + return [array1, array2].reduce((a, b) => a.filter((c) => !b.includes(c))); } +exports["default"] = arrayDifference; /***/ }), @@ -16009,7 +14339,7 @@ const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); const github = __nccwpck_require__(5438); const CONST = __nccwpck_require__(4097); -const GitHubUtils = __nccwpck_require__(7999); +const GitHubUtils = __nccwpck_require__(9296); const PR_NUMBER = Number.parseInt(core.getInput('PR_NUMBER'), 10) || github.context.payload.pull_request.number; diff --git a/.github/libs/GithubUtils.js b/.github/libs/GithubUtils.js deleted file mode 100644 index 0cd407c78153..000000000000 --- a/.github/libs/GithubUtils.js +++ /dev/null @@ -1,539 +0,0 @@ -const _ = require('underscore'); -const lodashGet = require('lodash/get'); -const core = require('@actions/core'); -const {GitHub, getOctokitOptions} = require('@actions/github/lib/utils'); -const {throttling} = require('@octokit/plugin-throttling'); -const {paginateRest} = require('@octokit/plugin-paginate-rest'); -const CONST = require('./CONST'); - -const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); -const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); -const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); -const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); - -/** - * The standard rate in ms at which we'll poll the GitHub API to check for status changes. - * It's 10 seconds :) - * @type {number} - */ -const POLL_RATE = 10000; - -class GithubUtils { - /** - * Initialize internal octokit - * - * @private - */ - static initOctokit() { - const Octokit = GitHub.plugin(throttling, paginateRest); - const token = core.getInput('GITHUB_TOKEN', {required: true}); - - // Save a copy of octokit used in this class - this.internalOctokit = new Octokit( - getOctokitOptions(token, { - throttle: { - retryAfterBaseValue: 2000, - onRateLimit: (retryAfter, options) => { - console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); - - // Retry five times when hitting a rate limit error, then give up - if (options.request.retryCount <= 5) { - console.log(`Retrying after ${retryAfter} seconds!`); - return true; - } - }, - onAbuseLimit: (retryAfter, options) => { - // does not retry, only logs a warning - console.warn(`Abuse detected for request ${options.method} ${options.url}`); - }, - }, - }), - ); - } - - /** - * Either give an existing instance of Octokit rest or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get octokit() { - if (this.internalOctokit) { - return this.internalOctokit.rest; - } - this.initOctokit(); - return this.internalOctokit.rest; - } - - /** - * Get the graphql instance from internal octokit. - * @readonly - * @static - * @memberof GithubUtils - */ - static get graphql() { - if (this.internalOctokit) { - return this.internalOctokit.graphql; - } - this.initOctokit(); - return this.internalOctokit.graphql; - } - - /** - * Either give an existing instance of Octokit paginate or create a new one - * - * @readonly - * @static - * @memberof GithubUtils - */ - static get paginate() { - if (this.internalOctokit) { - return this.internalOctokit.paginate; - } - this.initOctokit(); - return this.internalOctokit.paginate; - } - - /** - * Finds one open `StagingDeployCash` issue via GitHub octokit library. - * - * @returns {Promise} - */ - static getStagingDeployCash() { - return this.octokit.issues - .listForRepo({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - labels: CONST.LABELS.STAGING_DEPLOY, - state: 'open', - }) - .then(({data}) => { - if (!data.length) { - const error = new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 404; - throw error; - } - - if (data.length > 1) { - const error = new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); - error.code = 500; - throw error; - } - - return this.getStagingDeployCashData(data[0]); - }); - } - - /** - * Takes in a GitHub issue object and returns the data we want. - * - * @param {Object} issue - * @returns {Object} - */ - static getStagingDeployCashData(issue) { - try { - const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const tag = issue.body.match(versionRegex)[0].replace(/`/g, ''); - return { - title: issue.title, - url: issue.url, - number: this.getIssueOrPullRequestNumberFromURL(issue.url), - labels: issue.labels, - PRList: this.getStagingDeployCashPRList(issue), - deployBlockers: this.getStagingDeployCashDeployBlockers(issue), - internalQAPRList: this.getStagingDeployCashInternalQA(issue), - isTimingDashboardChecked: /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body), - isFirebaseChecked: /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body), - isGHStatusChecked: /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body), - tag, - }; - } catch (exception) { - throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); - } - } - - /** - * Parse the PRList and Internal QA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{url: String, number: Number, isVerified: Boolean}] - */ - static getStagingDeployCashPRList(issue) { - let PRListSection = issue.body.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) || []; - if (PRListSection.length !== 2) { - // No PRs, return an empty array - console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); - return []; - } - PRListSection = PRListSection[1]; - const PRList = _.map([...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isVerified: match[1] === 'x', - })); - return _.sortBy(PRList, 'number'); - } - - /** - * Parse DeployBlocker section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashDeployBlockers(issue) { - let deployBlockerSection = issue.body.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) || []; - if (deployBlockerSection.length !== 2) { - return []; - } - deployBlockerSection = deployBlockerSection[1]; - const deployBlockers = _.map([...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2], - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(deployBlockers, 'number'); - } - - /** - * Parse InternalQA section of the StagingDeployCash issue body. - * - * @private - * - * @param {Object} issue - * @returns {Array} - [{URL: String, number: Number, isResolved: Boolean}] - */ - static getStagingDeployCashInternalQA(issue) { - let internalQASection = issue.body.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) || []; - if (internalQASection.length !== 2) { - return []; - } - internalQASection = internalQASection[1]; - const internalQAPRs = _.map([...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))], (match) => ({ - url: match[2].split('-')[0].trim(), - number: Number.parseInt(match[3], 10), - isResolved: match[1] === 'x', - })); - return _.sortBy(internalQAPRs, 'number'); - } - - /** - * Generate the issue body for a StagingDeployCash. - * - * @param {String} tag - * @param {Array} PRList - The list of PR URLs which are included in this StagingDeployCash - * @param {Array} [verifiedPRList] - The list of PR URLs which have passed QA. - * @param {Array} [deployBlockers] - The list of DeployBlocker URLs. - * @param {Array} [resolvedDeployBlockers] - The list of DeployBlockers URLs which have been resolved. - * @param {Array} [resolvedInternalQAPRs] - The list of Internal QA PR URLs which have been resolved. - * @param {Boolean} [isTimingDashboardChecked] - * @param {Boolean} [isFirebaseChecked] - * @param {Boolean} [isGHStatusChecked] - * @returns {Promise} - */ - static generateStagingDeployCashBody( - tag, - PRList, - verifiedPRList = [], - deployBlockers = [], - resolvedDeployBlockers = [], - resolvedInternalQAPRs = [], - isTimingDashboardChecked = false, - isFirebaseChecked = false, - isGHStatusChecked = false, - ) { - return this.fetchAllPullRequests(_.map(PRList, this.getPullRequestNumberFromURL)) - .then((data) => { - // The format of this map is following: - // { - // 'https://github.com/Expensify/App/pull/9641': [ 'PauloGasparSv', 'kidroca' ], - // 'https://github.com/Expensify/App/pull/9642': [ 'mountiny', 'kidroca' ] - // } - const internalQAPRMap = _.reduce( - _.filter(data, (pr) => !_.isEmpty(_.findWhere(pr.labels, {name: CONST.LABELS.INTERNAL_QA}))), - (map, pr) => { - // eslint-disable-next-line no-param-reassign - map[pr.html_url] = _.compact(_.pluck(pr.assignees, 'login')); - return map; - }, - {}, - ); - console.log('Found the following Internal QA PRs:', internalQAPRMap); - - const noQAPRs = _.pluck( - _.filter(data, (PR) => /\[No\s?QA]/i.test(PR.title)), - 'html_url', - ); - console.log('Found the following NO QA PRs:', noQAPRs); - const verifiedOrNoQAPRs = _.union(verifiedPRList, noQAPRs); - - const sortedPRList = _.chain(PRList).difference(_.keys(internalQAPRMap)).unique().sortBy(GithubUtils.getPullRequestNumberFromURL).value(); - const sortedDeployBlockers = _.sortBy(_.unique(deployBlockers), GithubUtils.getIssueOrPullRequestNumberFromURL); - - // Tag version and comparison URL - // eslint-disable-next-line max-len - let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; - - // PR list - if (!_.isEmpty(sortedPRList)) { - issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; - _.each(sortedPRList, (URL) => { - issueBody += _.contains(verifiedOrNoQAPRs, URL) ? '- [x]' : '- [ ]'; - issueBody += ` ${URL}\r\n`; - }); - issueBody += '\r\n\r\n'; - } - - // Internal QA PR list - if (!_.isEmpty(internalQAPRMap)) { - console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); - issueBody += '**Internal QA:**\r\n'; - _.each(internalQAPRMap, (assignees, URL) => { - const assigneeMentions = _.reduce(assignees, (memo, assignee) => `${memo} @${assignee}`, ''); - issueBody += `${_.contains(resolvedInternalQAPRs, URL) ? '- [x]' : '- [ ]'} `; - issueBody += `${URL}`; - issueBody += ` -${assigneeMentions}`; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - // Deploy blockers - if (!_.isEmpty(deployBlockers)) { - issueBody += '**Deploy Blockers:**\r\n'; - _.each(sortedDeployBlockers, (URL) => { - issueBody += _.contains(resolvedDeployBlockers, URL) ? '- [x] ' : '- [ ] '; - issueBody += URL; - issueBody += '\r\n'; - }); - issueBody += '\r\n\r\n'; - } - - issueBody += '**Deployer verifications:**'; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isTimingDashboardChecked ? 'x' : ' ' - }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${ - isFirebaseChecked ? 'x' : ' ' - }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; - // eslint-disable-next-line max-len - issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; - - issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; - return issueBody; - }) - .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); - } - - /** - * Fetch all pull requests given a list of PR numbers. - * - * @param {Array} pullRequestNumbers - * @returns {Promise} - */ - static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = _.first(_.sortBy(pullRequestNumbers)); - return this.paginate( - this.octokit.pulls.list, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - state: 'all', - sort: 'created', - direction: 'desc', - per_page: 100, - }, - ({data}, done) => { - if (_.find(data, (pr) => pr.number === oldestPR)) { - done(); - } - return data; - }, - ) - .then((prList) => _.filter(prList, (pr) => _.contains(pullRequestNumbers, pr.number))) - .catch((err) => console.error('Failed to get PR list', err)); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getPullRequestBody(pullRequestNumber) { - return this.octokit.pulls - .get({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - }) - .then(({data: pullRequestComment}) => pullRequestComment.body); - } - - /** - * @param {Number} pullRequestNumber - * @returns {Promise} - */ - static getAllReviewComments(pullRequestNumber) { - return this.paginate( - this.octokit.pulls.listReviews, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - pull_number: pullRequestNumber, - per_page: 100, - }, - (response) => _.map(response.data, (review) => review.body), - ); - } - - /** - * @param {Number} issueNumber - * @returns {Promise} - */ - static getAllComments(issueNumber) { - return this.paginate( - this.octokit.issues.listComments, - { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }, - (response) => _.map(response.data, (comment) => comment.body), - ); - } - - /** - * Create comment on pull request - * - * @param {String} repo - The repo to search for a matching pull request or issue number - * @param {Number} number - The pull request or issue number - * @param {String} messageBody - The comment message - * @returns {Promise} - */ - static createComment(repo, number, messageBody) { - console.log(`Writing comment on #${number}`); - return this.octokit.issues.createComment({ - owner: CONST.GITHUB_OWNER, - repo, - issue_number: number, - body: messageBody, - }); - } - - /** - * Get the most recent workflow run for the given New Expensify workflow. - * - * @param {String} workflow - * @returns {Promise} - */ - static getLatestWorkflowRunID(workflow) { - console.log(`Fetching New Expensify workflow runs for ${workflow}...`); - return this.octokit.actions - .listWorkflowRuns({ - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - workflow_id: workflow, - }) - .then((response) => lodashGet(response, 'data.workflow_runs[0].id')); - } - - /** - * Generate the well-formatted body of a production release. - * - * @param {Array} pullRequests - * @returns {String} - */ - static getReleaseBody(pullRequests) { - return _.map(pullRequests, (number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } - - /** - * Generate the URL of an New Expensify pull request given the PR number. - * - * @param {Number} number - * @returns {String} - */ - static getPullRequestURLFromNumber(number) { - return `${CONST.APP_REPO_URL}/pull/${number}`; - } - - /** - * Parse the pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Pull Request. - */ - static getPullRequestNumberFromURL(URL) { - const matches = URL.match(PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue. - */ - static getIssueNumberFromURL(URL) { - const matches = URL.match(ISSUE_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a Github Issue!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Parse the issue or pull request number from a URL. - * - * @param {String} URL - * @returns {Number} - * @throws {Error} If the URL is not a valid Github Issue or Pull Request. - */ - static getIssueOrPullRequestNumberFromURL(URL) { - const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); - if (!_.isArray(matches) || matches.length !== 2) { - throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); - } - return Number.parseInt(matches[1], 10); - } - - /** - * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. - * - * @param {Number} issueNumber - * @returns {Promise} - */ - static getActorWhoClosedIssue(issueNumber) { - return this.paginate(this.octokit.issues.listEvents, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - issue_number: issueNumber, - per_page: 100, - }) - .then((events) => _.filter(events, (event) => event.event === 'closed')) - .then((closedEvents) => lodashGet(_.last(closedEvents), 'actor.login', '')); - } - - static getArtifactByName(artefactName) { - return this.paginate(this.octokit.actions.listArtifactsForRepo, { - owner: CONST.GITHUB_OWNER, - repo: CONST.APP_REPO, - per_page: 100, - }).then((artifacts) => _.findWhere(artifacts, {name: artefactName})); - } -} - -module.exports = GithubUtils; -module.exports.ISSUE_OR_PULL_REQUEST_REGEX = ISSUE_OR_PULL_REQUEST_REGEX; -module.exports.POLL_RATE = POLL_RATE; diff --git a/.github/libs/GithubUtils.ts b/.github/libs/GithubUtils.ts new file mode 100644 index 000000000000..52122702fb2d --- /dev/null +++ b/.github/libs/GithubUtils.ts @@ -0,0 +1,551 @@ +/* eslint-disable @typescript-eslint/naming-convention, import/no-import-module-exports */ +import * as core from '@actions/core'; +import {getOctokitOptions, GitHub} from '@actions/github/lib/utils'; +import type {Octokit as OctokitCore} from '@octokit/core'; +import type {graphql} from '@octokit/graphql/dist-types/types'; +import type {components as OctokitComponents} from '@octokit/openapi-types/types'; +import type {PaginateInterface} from '@octokit/plugin-paginate-rest'; +import {paginateRest} from '@octokit/plugin-paginate-rest'; +import type {RestEndpointMethodTypes} from '@octokit/plugin-rest-endpoint-methods'; +import type {RestEndpointMethods} from '@octokit/plugin-rest-endpoint-methods/dist-types/generated/method-types'; +import type {Api} from '@octokit/plugin-rest-endpoint-methods/dist-types/types'; +import {throttling} from '@octokit/plugin-throttling'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import arrayDifference from '@src/utils/arrayDifference'; +import CONST from './CONST'; + +const GITHUB_BASE_URL_REGEX = new RegExp('https?://(?:github\\.com|api\\.github\\.com)'); +const PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/pull/([0-9]+).*`); +const ISSUE_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/issues/([0-9]+).*`); +const ISSUE_OR_PULL_REQUEST_REGEX = new RegExp(`${GITHUB_BASE_URL_REGEX.source}/.*/.*/(?:pull|issues)/([0-9]+).*`); + +/** + * The standard rate in ms at which we'll poll the GitHub API to check for status changes. + * It's 10 seconds :) + */ +const POLL_RATE = 10000; + +type OctokitOptions = {method: string; url: string; request: {retryCount: number}}; + +type ListForRepoResult = RestEndpointMethodTypes['issues']['listForRepo']['response']; + +type OctokitIssueItem = OctokitComponents['schemas']['issue']; + +type ListForRepoMethod = RestEndpointMethods['issues']['listForRepo']; + +type StagingDeployCashPR = { + url: string; + number: number; + isVerified: boolean; +}; + +type StagingDeployCashBlocker = { + url: string; + number: number; + isResolved: boolean; +}; + +type StagingDeployCashBody = { + issueBody: string; + issueAssignees: Array; +}; + +type OctokitArtifact = OctokitComponents['schemas']['artifact']; + +type OctokitPR = OctokitComponents['schemas']['pull-request-simple']; + +type CreateCommentResponse = RestEndpointMethodTypes['issues']['createComment']['response']; + +type StagingDeployCashData = { + title: string; + url: string; + number: number; + labels: OctokitIssueItem['labels']; + PRList: StagingDeployCashPR[]; + deployBlockers: StagingDeployCashBlocker[]; + internalQAPRList: StagingDeployCashBlocker[]; + isTimingDashboardChecked: boolean; + isFirebaseChecked: boolean; + isGHStatusChecked: boolean; + tag?: string; +}; + +type InternalOctokit = OctokitCore & Api & {paginate: PaginateInterface}; + +class GithubUtils { + static internalOctokit: InternalOctokit | undefined; + + /** + * Initialize internal octokit + * + * @private + */ + static initOctokit() { + const Octokit = GitHub.plugin(throttling, paginateRest); + const token = core.getInput('GITHUB_TOKEN', {required: true}); + + // Save a copy of octokit used in this class + this.internalOctokit = new Octokit( + getOctokitOptions(token, { + throttle: { + retryAfterBaseValue: 2000, + onRateLimit: (retryAfter: number, options: OctokitOptions) => { + console.warn(`Request quota exhausted for request ${options.method} ${options.url}`); + + // Retry five times when hitting a rate limit error, then give up + if (options.request.retryCount <= 5) { + console.log(`Retrying after ${retryAfter} seconds!`); + return true; + } + }, + onAbuseLimit: (retryAfter: number, options: OctokitOptions) => { + // does not retry, only logs a warning + console.warn(`Abuse detected for request ${options.method} ${options.url}`); + }, + }, + }), + ); + } + + /** + * Either give an existing instance of Octokit rest or create a new one + * + * @readonly + * @static + */ + static get octokit(): RestEndpointMethods { + if (!this.internalOctokit) { + this.initOctokit(); + } + + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return (this.internalOctokit as InternalOctokit).rest; + } + + /** + * Get the graphql instance from internal octokit. + * @readonly + * @static + */ + static get graphql(): graphql { + if (!this.internalOctokit) { + this.initOctokit(); + } + + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return (this.internalOctokit as InternalOctokit).graphql; + } + + /** + * Either give an existing instance of Octokit paginate or create a new one + * + * @readonly + * @static + */ + static get paginate(): PaginateInterface { + if (!this.internalOctokit) { + this.initOctokit(); + } + + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + return (this.internalOctokit as InternalOctokit).paginate; + } + + /** + * Finds one open `StagingDeployCash` issue via GitHub octokit library. + */ + static getStagingDeployCash(): Promise { + return this.octokit.issues + .listForRepo({ + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + labels: CONST.LABELS.STAGING_DEPLOY, + state: 'open', + }) + .then(({data}: ListForRepoResult) => { + if (!data.length) { + throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue.`); + } + + if (data.length > 1) { + throw new Error(`Found more than one ${CONST.LABELS.STAGING_DEPLOY} issue.`); + } + + return this.getStagingDeployCashData(data[0]); + }); + } + + /** + * Takes in a GitHub issue object and returns the data we want. + */ + static getStagingDeployCashData(issue: OctokitIssueItem): StagingDeployCashData { + try { + const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); + const tag = issue.body?.match(versionRegex)?.[0].replace(/`/g, ''); + + return { + title: issue.title, + url: issue.url, + number: this.getIssueOrPullRequestNumberFromURL(issue.url), + labels: issue.labels, + PRList: this.getStagingDeployCashPRList(issue), + deployBlockers: this.getStagingDeployCashDeployBlockers(issue), + internalQAPRList: this.getStagingDeployCashInternalQA(issue), + isTimingDashboardChecked: issue.body ? /-\s\[x]\sI checked the \[App Timing Dashboard]/.test(issue.body) : false, + isFirebaseChecked: issue.body ? /-\s\[x]\sI checked \[Firebase Crashlytics]/.test(issue.body) : false, + isGHStatusChecked: issue.body ? /-\s\[x]\sI checked \[GitHub Status]/.test(issue.body) : false, + tag, + }; + } catch (exception) { + throw new Error(`Unable to find ${CONST.LABELS.STAGING_DEPLOY} issue with correct data.`); + } + } + + /** + * Parse the PRList and Internal QA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashPRList(issue: OctokitIssueItem): StagingDeployCashPR[] { + let PRListSection: RegExpMatchArray | string | null = issue.body?.match(/pull requests:\*\*\r?\n((?:-.*\r?\n)+)\r?\n\r?\n?/) ?? null; + if (PRListSection?.length !== 2) { + // No PRs, return an empty array + console.log('Hmmm...The open StagingDeployCash does not list any pull requests, continuing...'); + return []; + } + + PRListSection = PRListSection[1]; + const PRList = [...PRListSection.matchAll(new RegExp(`- \\[([ x])] (${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isVerified: match[1] === 'x', + })); + + return PRList.sort((a, b) => a.number - b.number); + } + + /** + * Parse DeployBlocker section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashDeployBlockers(issue: OctokitIssueItem): StagingDeployCashBlocker[] { + let deployBlockerSection: RegExpMatchArray | string | null = issue.body?.match(/Deploy Blockers:\*\*\r?\n((?:-.*\r?\n)+)/) ?? null; + if (deployBlockerSection?.length !== 2) { + return []; + } + + deployBlockerSection = deployBlockerSection[1]; + const deployBlockers = [...deployBlockerSection.matchAll(new RegExp(`- \\[([ x])]\\s(${ISSUE_OR_PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2], + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + + return deployBlockers.sort((a, b) => a.number - b.number); + } + + /** + * Parse InternalQA section of the StagingDeployCash issue body. + * + * @private + */ + static getStagingDeployCashInternalQA(issue: OctokitIssueItem): StagingDeployCashBlocker[] { + let internalQASection: RegExpMatchArray | string | null = issue.body?.match(/Internal QA:\*\*\r?\n((?:- \[[ x]].*\r?\n)+)/) ?? null; + if (internalQASection?.length !== 2) { + return []; + } + internalQASection = internalQASection[1]; + const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ + url: match[2].split('-')[0].trim(), + number: Number.parseInt(match[3], 10), + isResolved: match[1] === 'x', + })); + + return internalQAPRs.sort((a, b) => a.number - b.number); + } + + /** + * Generate the issue body and assignees for a StagingDeployCash. + */ + static generateStagingDeployCashBodyAndAssignees( + tag: string, + PRList: string[], + verifiedPRList: string[] = [], + deployBlockers: string[] = [], + resolvedDeployBlockers: string[] = [], + resolvedInternalQAPRs: string[] = [], + isTimingDashboardChecked = false, + isFirebaseChecked = false, + isGHStatusChecked = false, + ): Promise { + return this.fetchAllPullRequests(PRList.map((pr) => this.getPullRequestNumberFromURL(pr))) + .then((data) => { + const internalQAPRs = Array.isArray(data) ? data.filter((pr) => !isEmptyObject(pr.labels.find((item) => item.name === CONST.LABELS.INTERNAL_QA))) : []; + return Promise.all(internalQAPRs.map((pr) => this.getPullRequestMergerLogin(pr.number).then((mergerLogin) => ({url: pr.html_url, mergerLogin})))).then((results) => { + // The format of this map is following: + // { + // 'https://github.com/Expensify/App/pull/9641': 'PauloGasparSv', + // 'https://github.com/Expensify/App/pull/9642': 'mountiny' + // } + const internalQAPRMap = results.reduce>((acc, {url, mergerLogin}) => { + acc[url] = mergerLogin; + return acc; + }, {}); + console.log('Found the following Internal QA PRs:', internalQAPRMap); + + const noQAPRs = Array.isArray(data) ? data.filter((PR) => /\[No\s?QA]/i.test(PR.title)).map((item) => item.html_url) : []; + console.log('Found the following NO QA PRs:', noQAPRs); + const verifiedOrNoQAPRs = [...new Set([...verifiedPRList, ...noQAPRs])]; + + const sortedPRList = [...new Set(arrayDifference(PRList, Object.keys(internalQAPRMap)))].sort( + (a, b) => GithubUtils.getPullRequestNumberFromURL(a) - GithubUtils.getPullRequestNumberFromURL(b), + ); + const sortedDeployBlockers = [...new Set(deployBlockers)].sort( + (a, b) => GithubUtils.getIssueOrPullRequestNumberFromURL(a) - GithubUtils.getIssueOrPullRequestNumberFromURL(b), + ); + + // Tag version and comparison URL + // eslint-disable-next-line max-len + let issueBody = `**Release Version:** \`${tag}\`\r\n**Compare Changes:** https://github.com/Expensify/App/compare/production...staging\r\n`; + + // PR list + if (sortedPRList.length > 0) { + issueBody += '\r\n**This release contains changes from the following pull requests:**\r\n'; + sortedPRList.forEach((URL) => { + issueBody += verifiedOrNoQAPRs.includes(URL) ? '- [x]' : '- [ ]'; + issueBody += ` ${URL}\r\n`; + }); + issueBody += '\r\n\r\n'; + } + + // Internal QA PR list + if (!isEmptyObject(internalQAPRMap)) { + console.log('Found the following verified Internal QA PRs:', resolvedInternalQAPRs); + issueBody += '**Internal QA:**\r\n'; + Object.keys(internalQAPRMap).forEach((URL) => { + const merger = internalQAPRMap[URL]; + const mergerMention = `@${merger}`; + issueBody += `${resolvedInternalQAPRs.includes(URL) ? '- [x]' : '- [ ]'} `; + issueBody += `${URL}`; + issueBody += ` - ${mergerMention}`; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + + // Deploy blockers + if (deployBlockers.length > 0) { + issueBody += '**Deploy Blockers:**\r\n'; + sortedDeployBlockers.forEach((URL) => { + issueBody += resolvedDeployBlockers.includes(URL) ? '- [x] ' : '- [ ] '; + issueBody += URL; + issueBody += '\r\n'; + }); + issueBody += '\r\n\r\n'; + } + + issueBody += '**Deployer verifications:**'; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${ + isTimingDashboardChecked ? 'x' : ' ' + }] I checked the [App Timing Dashboard](https://graphs.expensify.com/grafana/d/yj2EobAGz/app-timing?orgId=1) and verified this release does not cause a noticeable performance regression.`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${ + isFirebaseChecked ? 'x' : ' ' + }] I checked [Firebase Crashlytics](https://console.firebase.google.com/u/0/project/expensify-chat/crashlytics/app/android:com.expensify.chat/issues?state=open&time=last-seven-days&tag=all) and verified that this release does not introduce any new crashes. More detailed instructions on this verification can be found [here](https://stackoverflowteams.com/c/expensify/questions/15095/15096).`; + // eslint-disable-next-line max-len + issueBody += `\r\n- [${isGHStatusChecked ? 'x' : ' '}] I checked [GitHub Status](https://www.githubstatus.com/) and verified there is no reported incident with Actions.`; + + issueBody += '\r\n\r\ncc @Expensify/applauseleads\r\n'; + const issueAssignees = [...new Set(Object.values(internalQAPRMap))]; + const issue = {issueBody, issueAssignees}; + return issue; + }); + }) + .catch((err) => console.warn('Error generating StagingDeployCash issue body! Continuing...', err)); + } + + /** + * Fetch all pull requests given a list of PR numbers. + */ + static fetchAllPullRequests(pullRequestNumbers: number[]): Promise { + const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + return this.paginate( + this.octokit.pulls.list, + { + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + state: 'all', + sort: 'created', + direction: 'desc', + per_page: 100, + }, + ({data}, done) => { + if (data.find((pr) => pr.number === oldestPR)) { + done(); + } + return data; + }, + ) + .then((prList) => prList.filter((pr) => pullRequestNumbers.includes(pr.number))) + .catch((err) => console.error('Failed to get PR list', err)); + } + + static getPullRequestMergerLogin(pullRequestNumber: number): Promise { + return this.octokit.pulls + .get({ + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({data: pullRequest}) => pullRequest.merged_by?.login); + } + + static getPullRequestBody(pullRequestNumber: number): Promise { + return this.octokit.pulls + .get({ + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + pull_number: pullRequestNumber, + }) + .then(({data: pullRequestComment}) => pullRequestComment.body); + } + + static getAllReviewComments(pullRequestNumber: number): Promise { + return this.paginate( + this.octokit.pulls.listReviews, + { + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + pull_number: pullRequestNumber, + per_page: 100, + }, + (response) => response.data.map((review) => review.body), + ); + } + + static getAllComments(issueNumber: number): Promise> { + return this.paginate( + this.octokit.issues.listComments, + { + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }, + (response) => response.data.map((comment) => comment.body), + ); + } + + /** + * Create comment on pull request + */ + static createComment(repo: string, number: number, messageBody: string): Promise { + console.log(`Writing comment on #${number}`); + return this.octokit.issues.createComment({ + owner: CONST.GITHUB_OWNER, + repo, + issue_number: number, + body: messageBody, + }); + } + + /** + * Get the most recent workflow run for the given New Expensify workflow. + */ + static getLatestWorkflowRunID(workflow: string | number): Promise { + console.log(`Fetching New Expensify workflow runs for ${workflow}...`); + return this.octokit.actions + .listWorkflowRuns({ + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + workflow_id: workflow, + }) + .then((response) => response.data.workflow_runs[0]?.id); + } + + /** + * Generate the well-formatted body of a production release. + */ + static getReleaseBody(pullRequests: number[]): string { + return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); + } + + /** + * Generate the URL of an New Expensify pull request given the PR number. + */ + static getPullRequestURLFromNumber(value: number): string { + // @ts-expect-error TODO: Remove this once CONST.js (https://github.com/Expensify/App/issues/25362) is migrated to TypeScript + return `${CONST.APP_REPO_URL}/pull/${value}`; + } + + /** + * Parse the pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Pull Request. + */ + static getPullRequestNumberFromURL(URL: string): number { + const matches = URL.match(PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + + /** + * Parse the issue number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue. + */ + static getIssueNumberFromURL(URL: string): number { + const matches = URL.match(ISSUE_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a Github Issue!`); + } + return Number.parseInt(matches[1], 10); + } + + /** + * Parse the issue or pull request number from a URL. + * + * @throws {Error} If the URL is not a valid Github Issue or Pull Request. + */ + static getIssueOrPullRequestNumberFromURL(URL: string): number { + const matches = URL.match(ISSUE_OR_PULL_REQUEST_REGEX); + if (!Array.isArray(matches) || matches.length !== 2) { + throw new Error(`Provided URL ${URL} is not a valid Github Issue or Pull Request!`); + } + return Number.parseInt(matches[1], 10); + } + + /** + * Return the login of the actor who closed an issue or PR. If the issue is not closed, return an empty string. + */ + static getActorWhoClosedIssue(issueNumber: number): Promise { + return this.paginate(this.octokit.issues.listEvents, { + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + issue_number: issueNumber, + per_page: 100, + }) + .then((events) => events.filter((event) => event.event === 'closed')) + .then((closedEvents) => closedEvents.at(-1)?.actor?.login ?? ''); + } + + static getArtifactByName(artefactName: string): Promise { + return this.paginate(this.octokit.actions.listArtifactsForRepo, { + owner: CONST.GITHUB_OWNER, + repo: CONST.APP_REPO, + per_page: 100, + }).then((artifacts: OctokitArtifact[]) => artifacts.find((artifact) => artifact.name === artefactName)); + } +} + +export default GithubUtils; +// This is a temporary solution to allow the use of the GithubUtils class in both TypeScript and JavaScript. +// Once all the files that import GithubUtils are migrated to TypeScript, this can be removed. +module.exports = GithubUtils; + +export {ISSUE_OR_PULL_REQUEST_REGEX, POLL_RATE}; +export type {ListForRepoMethod, InternalOctokit, CreateCommentResponse}; diff --git a/.github/libs/nativeVersionUpdater.js b/.github/libs/nativeVersionUpdater.ts similarity index 64% rename from .github/libs/nativeVersionUpdater.js rename to .github/libs/nativeVersionUpdater.ts index ab129f4eb04a..4ecf9d64966c 100644 --- a/.github/libs/nativeVersionUpdater.js +++ b/.github/libs/nativeVersionUpdater.ts @@ -1,10 +1,11 @@ -const {execSync} = require('child_process'); -const fs = require('fs').promises; -const path = require('path'); -const getMajorVersion = require('semver/functions/major'); -const getMinorVersion = require('semver/functions/minor'); -const getPatchVersion = require('semver/functions/patch'); -const getBuildVersion = require('semver/functions/prerelease'); +import {execSync} from 'child_process'; +import {promises as fs} from 'fs'; +import path from 'path'; +import type {SemVer} from 'semver'; +import getMajorVersion from 'semver/functions/major'; +import getMinorVersion from 'semver/functions/minor'; +import getPatchVersion from 'semver/functions/patch'; +import getBuildVersion from 'semver/functions/prerelease'; // Filepath constants const BUILD_GRADLE_PATH = process.env.NODE_ENV === 'test' ? path.resolve(__dirname, '../../android/app/build.gradle') : './android/app/build.gradle'; @@ -12,51 +13,37 @@ const PLIST_PATH = './ios/NewExpensify/Info.plist'; const PLIST_PATH_TEST = './ios/NewExpensifyTests/Info.plist'; const PLIST_PATH_NSE = './ios/NotificationServiceExtension/Info.plist'; -exports.BUILD_GRADLE_PATH = BUILD_GRADLE_PATH; -exports.PLIST_PATH = PLIST_PATH; -exports.PLIST_PATH_TEST = PLIST_PATH_TEST; - /** * Pad a number to be two digits (with leading zeros if necessary). - * - * @param {Number} number - Must be an integer. - * @returns {String} - A string representation of the number with length 2. */ -function padToTwoDigits(number) { - if (number >= 10) { - return number.toString(); +function padToTwoDigits(value: number): string { + if (value >= 10) { + return value.toString(); } - return `0${number.toString()}`; + return `0${value.toString()}`; } /** * Generate the 10-digit versionCode for android. * This version code allocates two digits each for PREFIX, MAJOR, MINOR, PATCH, and BUILD versions. * As a result, our max version is 99.99.99-99. - * - * @param {String} npmVersion - * @returns {String} */ -exports.generateAndroidVersionCode = function generateAndroidVersionCode(npmVersion) { +function generateAndroidVersionCode(npmVersion: string | SemVer): string { // All Android versions will be prefixed with '10' due to previous versioning const prefix = '10'; return ''.concat( prefix, - padToTwoDigits(getMajorVersion(npmVersion) || 0), - padToTwoDigits(getMinorVersion(npmVersion) || 0), - padToTwoDigits(getPatchVersion(npmVersion) || 0), - padToTwoDigits(getBuildVersion(npmVersion) || 0), + padToTwoDigits(getMajorVersion(npmVersion) ?? 0), + padToTwoDigits(getMinorVersion(npmVersion) ?? 0), + padToTwoDigits(getPatchVersion(npmVersion) ?? 0), + padToTwoDigits(Number(getBuildVersion(npmVersion)) ?? 0), ); -}; +} /** * Update the Android app versionName and versionCode. - * - * @param {String} versionName - * @param {String} versionCode - * @returns {Promise} */ -exports.updateAndroidVersion = function updateAndroidVersion(versionName, versionCode) { +function updateAndroidVersion(versionName: string, versionCode: string): Promise { console.log('Updating android:', `versionName: ${versionName}`, `versionCode: ${versionCode}`); return fs .readFile(BUILD_GRADLE_PATH, {encoding: 'utf8'}) @@ -65,16 +52,13 @@ exports.updateAndroidVersion = function updateAndroidVersion(versionName, versio return (updatedContent = updatedContent.replace(/versionCode ([0-9]*)/, `versionCode ${versionCode}`)); }) .then((updatedContent) => fs.writeFile(BUILD_GRADLE_PATH, updatedContent, {encoding: 'utf8'})); -}; +} /** * Update the iOS app version. * Updates the CFBundleShortVersionString and the CFBundleVersion. - * - * @param {String} version - * @returns {String} */ -exports.updateiOSVersion = function updateiOSVersion(version) { +function updateiOSVersion(version: string): string { const shortVersion = version.split('-')[0]; const cfVersion = version.includes('-') ? version.replace('-', '.') : `${version}.0`; console.log('Updating iOS', `CFBundleShortVersionString: ${shortVersion}`, `CFBundleVersion: ${cfVersion}`); @@ -89,4 +73,6 @@ exports.updateiOSVersion = function updateiOSVersion(version) { // Return the cfVersion so we can set the NEW_IOS_VERSION in ios.yml return cfVersion; -}; +} + +export {updateiOSVersion, updateAndroidVersion, generateAndroidVersionCode, BUILD_GRADLE_PATH, PLIST_PATH, PLIST_PATH_TEST}; diff --git a/.github/scripts/buildActions.sh b/.github/scripts/buildActions.sh index 48acb931aeec..df90e3351cc0 100755 --- a/.github/scripts/buildActions.sh +++ b/.github/scripts/buildActions.sh @@ -10,7 +10,7 @@ ACTIONS_DIR="$(dirname "$(dirname "$0")")/actions/javascript" # List of paths to all JS files that implement our GH Actions declare -r GITHUB_ACTIONS=( "$ACTIONS_DIR/awaitStagingDeploys/awaitStagingDeploys.js" - "$ACTIONS_DIR/bumpVersion/bumpVersion.js" + "$ACTIONS_DIR/bumpVersion/bumpVersion.ts" "$ACTIONS_DIR/checkDeployBlockers/checkDeployBlockers.js" "$ACTIONS_DIR/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js" "$ACTIONS_DIR/getDeployPullRequestList/getDeployPullRequestList.js" @@ -18,7 +18,7 @@ declare -r GITHUB_ACTIONS=( "$ACTIONS_DIR/getPullRequestDetails/getPullRequestDetails.js" "$ACTIONS_DIR/getReleaseBody/getReleaseBody.js" "$ACTIONS_DIR/isStagingDeployLocked/isStagingDeployLocked.js" - "$ACTIONS_DIR/markPullRequestsAsDeployed/markPullRequestsAsDeployed.js" + "$ACTIONS_DIR/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts" "$ACTIONS_DIR/postTestBuildComment/postTestBuildComment.js" "$ACTIONS_DIR/reopenIssueWithComment/reopenIssueWithComment.js" "$ACTIONS_DIR/verifySignedCommits/verifySignedCommits.js" @@ -43,7 +43,7 @@ for ((i=0; i < ${#GITHUB_ACTIONS[@]}; i++)); do ACTION_DIR=$(dirname "$ACTION") # Build the action in the background - ncc build "$ACTION" -o "$ACTION_DIR" & + ncc build -t "$ACTION" -o "$ACTION_DIR" & ASYNC_BUILDS[i]=$! done diff --git a/.github/workflows/authorChecklist.yml b/.github/workflows/authorChecklist.yml index 907b1e7be6ca..2bc94cffefd8 100644 --- a/.github/workflows/authorChecklist.yml +++ b/.github/workflows/authorChecklist.yml @@ -16,7 +16,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: authorChecklist.js + - name: authorChecklist.ts uses: ./.github/actions/javascript/authorChecklist with: GITHUB_TOKEN: ${{ github.token }} diff --git a/.prettierrc.js b/.prettierrc.js index 5c9b25ec472a..3118dc378694 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -11,6 +11,7 @@ module.exports = { '@assets/(.*)$', '@components/(.*)$', '@desktop/(.*)$', + '@github/(.*)$', '@hooks/(.*)$', '@libs/(.*)$', '@navigation/(.*)$', diff --git a/.storybook/main.js b/.storybook/main.ts similarity index 67% rename from .storybook/main.js rename to .storybook/main.ts index 7d063fd6ffe1..33f4befb0f40 100644 --- a/.storybook/main.js +++ b/.storybook/main.ts @@ -1,12 +1,20 @@ -module.exports = { +import type {StorybookConfig} from '@storybook/core-common'; + +type Main = { + managerHead: (head: string) => string; +} & StorybookConfig; + +const main: Main = { stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: ['@storybook/addon-essentials', '@storybook/addon-a11y', '@storybook/addon-react-native-web'], staticDirs: ['./public', {from: '../assets/css', to: 'css'}, {from: '../assets/fonts/web', to: 'fonts'}], core: { builder: 'webpack5', }, - managerHead: (head) => ` + managerHead: (head: string) => ` ${head} ${process.env.ENV === 'staging' ? '' : ''} `, }; + +export default main; diff --git a/.storybook/manager.js b/.storybook/manager.ts similarity index 100% rename from .storybook/manager.js rename to .storybook/manager.ts diff --git a/.storybook/preview.js b/.storybook/preview.tsx similarity index 53% rename from .storybook/preview.js rename to .storybook/preview.tsx index a89c720976c9..4767c7d81343 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.tsx @@ -1,15 +1,16 @@ import {PortalProvider} from '@gorhom/portal'; +import type {Parameters} from '@storybook/addons'; import React from 'react'; import Onyx from 'react-native-onyx'; import {SafeAreaProvider} from 'react-native-safe-area-context'; -import ComposeProviders from '../src/components/ComposeProviders'; -import HTMLEngineProvider from '../src/components/HTMLEngineProvider'; -import {LocaleContextProvider} from '../src/components/LocaleContextProvider'; -import OnyxProvider from '../src/components/OnyxProvider'; -import {EnvironmentProvider} from '../src/components/withEnvironment'; -import {KeyboardStateProvider} from '../src/components/withKeyboardState'; -import {WindowDimensionsProvider} from '../src/components/withWindowDimensions'; -import ONYXKEYS from '../src/ONYXKEYS'; +import ComposeProviders from '@src/components/ComposeProviders'; +import HTMLEngineProvider from '@src/components/HTMLEngineProvider'; +import {LocaleContextProvider} from '@src/components/LocaleContextProvider'; +import OnyxProvider from '@src/components/OnyxProvider'; +import {EnvironmentProvider} from '@src/components/withEnvironment'; +import {KeyboardStateProvider} from '@src/components/withKeyboardState'; +import {WindowDimensionsProvider} from '@src/components/withWindowDimensions'; +import ONYXKEYS from '@src/ONYXKEYS'; import './fonts.css'; Onyx.init({ @@ -20,7 +21,7 @@ Onyx.init({ }); const decorators = [ - (Story) => ( + (Story: React.ElementType) => ( @@ -29,7 +30,7 @@ const decorators = [ ), ]; -const parameters = { +const parameters: Parameters = { controls: { matchers: { color: /(background|color)$/i, diff --git a/.storybook/theme.js b/.storybook/theme.ts similarity index 80% rename from .storybook/theme.js rename to .storybook/theme.ts index 08d8b584d580..a28a0f031b0c 100644 --- a/.storybook/theme.js +++ b/.storybook/theme.ts @@ -1,7 +1,9 @@ +import type {ThemeVars} from '@storybook/theming'; import {create} from '@storybook/theming'; +// eslint-disable-next-line @dword-design/import-alias/prefer-alias import colors from '../src/styles/theme/colors'; -export default create({ +const theme: ThemeVars = create({ brandTitle: 'New Expensify UI Docs', brandImage: 'logomark.svg', fontBase: 'ExpensifyNeue-Regular', @@ -21,3 +23,5 @@ export default create({ appBorderRadius: 8, inputBorderRadius: 8, }); + +export default theme; diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js deleted file mode 100644 index 204f70344b18..000000000000 --- a/.storybook/webpack.config.js +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -/* eslint-disable no-param-reassign */ -const path = require('path'); -const dotenv = require('dotenv'); -const _ = require('underscore'); - -let envFile; -switch (process.env.ENV) { - case 'production': - envFile = '.env.production'; - break; - case 'staging': - envFile = '.env.staging'; - break; - default: - envFile = '.env'; -} - -const env = dotenv.config({path: path.resolve(__dirname, `../${envFile}`)}); -const custom = require('../config/webpack/webpack.common')({ - envFile, -}); - -module.exports = ({config}) => { - config.resolve.alias = { - 'react-native-config': 'react-web-config', - 'react-native$': 'react-native-web', - '@react-native-community/netinfo': path.resolve(__dirname, '../__mocks__/@react-native-community/netinfo.ts'), - '@react-navigation/native': path.resolve(__dirname, '../__mocks__/@react-navigation/native'), - - // Module alias support for storybook files, coping from `webpack.common.js` - ...custom.resolve.alias, - }; - - // Necessary to overwrite the values in the existing DefinePlugin hardcoded to the Config staging values - const definePluginIndex = _.findIndex(config.plugins, (plugin) => plugin.constructor.name === 'DefinePlugin'); - config.plugins[definePluginIndex].definitions.__REACT_WEB_CONFIG__ = JSON.stringify(env); - config.resolve.extensions = custom.resolve.extensions; - - const babelRulesIndex = _.findIndex(custom.module.rules, (rule) => rule.loader === 'babel-loader'); - const babelRule = custom.module.rules[babelRulesIndex]; - config.module.rules.push(babelRule); - - // Allows loading SVG - more context here https://github.com/storybookjs/storybook/issues/6188 - const fileLoaderRule = _.find(config.module.rules, (rule) => rule.test && rule.test.test('.svg')); - fileLoaderRule.exclude = /\.svg$/; - config.module.rules.push({ - test: /\.svg$/, - enforce: 'pre', - loader: require.resolve('@svgr/webpack'), - }); - - return config; -}; diff --git a/.storybook/webpack.config.ts b/.storybook/webpack.config.ts new file mode 100644 index 000000000000..2fdae76c1268 --- /dev/null +++ b/.storybook/webpack.config.ts @@ -0,0 +1,81 @@ +/* eslint-disable no-underscore-dangle */ + +/* eslint-disable no-param-reassign */ + +/* eslint-disable @typescript-eslint/naming-convention */ +import dotenv from 'dotenv'; +import path from 'path'; +import {DefinePlugin} from 'webpack'; +import type {Configuration, RuleSetRule} from 'webpack'; + +type CustomWebpackConfig = { + resolve: { + alias: Record; + extensions: string[]; + }; + module: { + rules: RuleSetRule[]; + }; +}; + +let envFile: string; +switch (process.env.ENV) { + case 'production': + envFile = '.env.production'; + break; + case 'staging': + envFile = '.env.staging'; + break; + default: + envFile = '.env'; +} + +const env = dotenv.config({path: path.resolve(__dirname, `../${envFile}`)}); +const custom: CustomWebpackConfig = require('../config/webpack/webpack.common')({ + envFile, +}); + +const webpackConfig = ({config}: {config: Configuration}) => { + if (config.resolve && config.plugins && config.module) { + config.resolve.alias = { + 'react-native-config': 'react-web-config', + 'react-native$': 'react-native-web', + '@react-native-community/netinfo': path.resolve(__dirname, '../__mocks__/@react-native-community/netinfo.ts'), + '@react-navigation/native': path.resolve(__dirname, '../__mocks__/@react-navigation/native'), + ...custom.resolve.alias, + }; + + // Necessary to overwrite the values in the existing DefinePlugin hardcoded to the Config staging values + const definePluginIndex = config.plugins.findIndex((plugin) => plugin instanceof DefinePlugin); + if (definePluginIndex !== -1 && config.plugins[definePluginIndex] instanceof DefinePlugin) { + const definePlugin = config.plugins[definePluginIndex] as DefinePlugin; + if (definePlugin.definitions) { + definePlugin.definitions.__REACT_WEB_CONFIG__ = JSON.stringify(env); + } + } + config.resolve.extensions = custom.resolve.extensions; + + const babelRulesIndex = custom.module.rules.findIndex((rule) => rule.loader === 'babel-loader'); + const babelRule = custom.module.rules[babelRulesIndex]; + if (babelRule) { + config.module.rules?.push(babelRule); + } + + const fileLoaderRule = config.module.rules?.find( + (rule): rule is RuleSetRule => + typeof rule !== 'boolean' && typeof rule !== 'string' && typeof rule !== 'number' && !!rule?.test && rule.test instanceof RegExp && rule.test.test('.svg'), + ); + if (fileLoaderRule) { + fileLoaderRule.exclude = /\.svg$/; + } + config.module.rules?.push({ + test: /\.svg$/, + enforce: 'pre', + loader: require.resolve('@svgr/webpack'), + }); + } + + return config; +}; + +export default webpackConfig; diff --git a/__mocks__/@react-native-clipboard/clipboard.js b/__mocks__/@react-native-clipboard/clipboard.js deleted file mode 100644 index e56e290c3cc9..000000000000 --- a/__mocks__/@react-native-clipboard/clipboard.js +++ /dev/null @@ -1,3 +0,0 @@ -import MockClipboard from '@react-native-clipboard/clipboard/jest/clipboard-mock'; - -export default MockClipboard; diff --git a/__mocks__/@react-native-clipboard/clipboard.ts b/__mocks__/@react-native-clipboard/clipboard.ts new file mode 100644 index 000000000000..75b6f09f5345 --- /dev/null +++ b/__mocks__/@react-native-clipboard/clipboard.ts @@ -0,0 +1,3 @@ +import clipboardMock from '@react-native-clipboard/clipboard/jest/clipboard-mock'; + +export default clipboardMock; diff --git a/__mocks__/pusher-js/react-native.js b/__mocks__/pusher-js/react-native.ts similarity index 100% rename from __mocks__/pusher-js/react-native.js rename to __mocks__/pusher-js/react-native.ts diff --git a/__mocks__/react-native-document-picker.js b/__mocks__/react-native-document-picker.ts similarity index 64% rename from __mocks__/react-native-document-picker.js rename to __mocks__/react-native-document-picker.ts index 8cba2bc1eba4..6d26a0227fc3 100644 --- a/__mocks__/react-native-document-picker.js +++ b/__mocks__/react-native-document-picker.ts @@ -1,9 +1,16 @@ -export default { - getConstants: jest.fn(), +import type {pick, pickDirectory, releaseSecureAccess, types} from 'react-native-document-picker'; + +type ReactNativeDocumentPickerMock = { + pick: typeof pick; + releaseSecureAccess: typeof releaseSecureAccess; + pickDirectory: typeof pickDirectory; + types: typeof types; +}; + +const reactNativeDocumentPickerMock: ReactNativeDocumentPickerMock = { pick: jest.fn(), releaseSecureAccess: jest.fn(), pickDirectory: jest.fn(), - types: Object.freeze({ allFiles: 'public.item', audio: 'public.audio', @@ -21,3 +28,5 @@ export default { zip: 'public.zip-archive', }), }; + +export default reactNativeDocumentPickerMock; diff --git a/android/app/build.gradle b/android/app/build.gradle index 9c5db608a846..0b2271d16716 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001045503 - versionName "1.4.55-3" + versionCode 1001045605 + versionName "1.4.56-5" } flavorDimensions "default" diff --git a/assets/images/money-waving.svg b/assets/images/money-waving.svg new file mode 100644 index 000000000000..5242e31092a0 --- /dev/null +++ b/assets/images/money-waving.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/babel.config.js b/babel.config.js index 7e90fca1c9be..9f8b7a711d78 100644 --- a/babel.config.js +++ b/babel.config.js @@ -69,6 +69,7 @@ const metro = { '@src': './src', '@userActions': './src/libs/actions', '@desktop': './desktop', + '@github': './.github', }, }, ], diff --git a/desktop/package-lock.json b/desktop/package-lock.json index b8ae9d0a2be5..efa8a25a0614 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -10,7 +10,7 @@ "electron-context-menu": "^2.3.0", "electron-log": "^4.4.8", "electron-serve": "^1.3.0", - "electron-updater": "^6.1.9", + "electron-updater": "^6.2.1", "node-machine-id": "^1.1.12" } }, @@ -156,9 +156,9 @@ } }, "node_modules/electron-updater": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.1.9.tgz", - "integrity": "sha512-omoTwGSG+/H8G62cEZS/dc5Lmc4HohAd4198AP+JNv8H7bfxXUCKekaR6WpsN1n2DiWzvcqOusfGSogZv/uj9w==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz", + "integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==", "dependencies": { "builder-util-runtime": "9.2.4", "fs-extra": "^10.1.0", @@ -541,9 +541,9 @@ "integrity": "sha512-OEC/48ZBJxR6XNSZtCl4cKPyQ1lvsu8yp8GdCplMWwGS1eEyMcEmzML5BRs/io/RLDnpgyf+7rSL+X6ICifRIg==" }, "electron-updater": { - "version": "6.1.9", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.1.9.tgz", - "integrity": "sha512-omoTwGSG+/H8G62cEZS/dc5Lmc4HohAd4198AP+JNv8H7bfxXUCKekaR6WpsN1n2DiWzvcqOusfGSogZv/uj9w==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.2.1.tgz", + "integrity": "sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==", "requires": { "builder-util-runtime": "9.2.4", "fs-extra": "^10.1.0", diff --git a/desktop/package.json b/desktop/package.json index 606fcac92500..4249f3fcfba9 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -7,7 +7,7 @@ "electron-context-menu": "^2.3.0", "electron-log": "^4.4.8", "electron-serve": "^1.3.0", - "electron-updater": "^6.1.9", + "electron-updater": "^6.2.1", "node-machine-id": "^1.1.12" }, "author": "Expensify, Inc.", diff --git a/docs/_sass/_colors.scss b/docs/_sass/_colors.scss index f0c89d31c580..1f5c43ac7ae2 100644 --- a/docs/_sass/_colors.scss +++ b/docs/_sass/_colors.scss @@ -1,36 +1,41 @@ -// Product Color Spectrum -$color-product-dark-100: #061B09; -$color-product-dark-200: #072419; -$color-product-dark-300: #0A2E25; -$color-product-dark-400: #1A3D32; -$color-product-dark-500: #224F41; -$color-product-dark-600: #2A604F; -$color-product-dark-700: #8B9C8F; -$color-product-dark-800: #AFBBB0; -$color-product-dark-900: #E7ECE9; +:root { + --color-text: #002e22; + --color-button-text: #FCFBF9; + --color-text-supporting: #76847e; + --color-icons: #a2a9a3; + --color-borders: #e6e1da; + --color-highlightBG: #f8f4f0; + --color-row-hover: #f2ede7; + --color-appBG: #fcfbf9; + --color-success: #03d47c; + --color-accent: #03d47c; + --color-link: #0164BF; + --color-link-hovered: #0676DE; + --color-button-background: #e6e1da; + --color-button-background-hover: #d8d1c7; + --color-button-success-background: #03d47c; + --color-button-success-background-hover: #00a862; + --color-overlay: rgba(235, 230, 223, 0.72); +} -// Colors for Links and Success -$color-blue200: #B0D9FF; -$color-blue300: #5AB0FF; -$color-green400: #03D47C; -$color-green500: #00a862; - -// Overlay BG color -$color-overlay-background: rgba(26, 61, 50, 0.72); - -// UI Colors -$color-text: $color-product-dark-900; -$color-text-supporting: $color-product-dark-800; -$color-icons: $color-product-dark-700; -$color-borders: $color-product-dark-400; -$color-highlightBG: $color-product-dark-200; -$color-row-hover: $color-product-dark-300; -$color-appBG: $color-product-dark-100; -$color-success: $color-green400; -$color-accent : $color-green400; -$color-link: $color-blue300; -$color-link-hovered: $color-blue200; -$color-button-background: $color-product-dark-400; -$color-button-background-hover: $color-product-dark-500; -$color-button-success-background: $color-green400; -$color-button-success-background-hover: $color-green500; +@media (prefers-color-scheme: dark) { + :root { + --color-text: #e7ece9; + --color-button-text: #E7ECE9; + --color-text-supporting: #afbbb0; + --color-icons: #8b9c8f; + --color-borders: #1a3d32; + --color-highlightBG: #072419; + --color-row-hover: #0a2e25; + --color-appBG: #061b09; + --color-success: #03d47c; + --color-accent: #03d47c; + --color-link: #5ab0ff; + --color-link-hovered: #8DC8FF; + --color-button-background: #1a3d32; + --color-button-background-hover: #224f41; + --color-button-success-background: #03d47c; + --color-button-success-background-hover: #00a862; + --color-overlay: rgba(26, 61, 50, 0.72); + } +} diff --git a/docs/_sass/_main.scss b/docs/_sass/_main.scss index ec0f76801bc7..ae19775d75df 100644 --- a/docs/_sass/_main.scss +++ b/docs/_sass/_main.scss @@ -62,12 +62,12 @@ html, body { height: 100%; min-height: 100%; - background: $color-appBG; - color: $color-text-supporting; + background: var(--color-appBG); + color: var(--color-text-supporting); } hr { - background: $color-borders; + background: var(--color-borders); border: none; display: inline-block; width: 24px; @@ -84,7 +84,7 @@ em { } a { - color: $color-link; + color: var(--color-link); text-decoration: none; img { @@ -97,9 +97,9 @@ h2, h3, h4, h5, -h6, +h6, summary { - color: $color-text; + color: var(--color-text); font-weight: bold; padding-bottom: 12px; } @@ -116,22 +116,22 @@ h6 { font-size: 1.5em; } -details summary { +details summary { cursor: pointer; user-select: none; } details > summary { - list-style-image: url("/assets/images/arrow-right.svg"); + list-style-image: url('/assets/images/arrow-right.svg'); } details[open] > summary { - list-style-image: url("/assets/images/down.svg"); + list-style-image: url('/assets/images/down.svg'); } -h1, +h1, summary { - font-family: "ExpensifyNewKansas", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNewKansas', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; font-weight: 500; font-size: larger; } @@ -151,28 +151,28 @@ select, textarea { line-height: 1.4; font-weight: 400; - font-family: "ExpensifyNeue", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNeue', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; font-size: 16px; - color: $color-text-supporting; + color: var(--color-text-supporting); } button { border-radius: 12px; padding: 12px; - font-family: "ExpensifyNeue", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNeue', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; font-size: 15px; font-weight: bold; &.success { - background-color: $color-button-success-background; - color: $color-text; + background-color: var(--color-button-success-background); + color: var(--color-button-text); width: 100%; border-radius: 100px; padding-left: 20px; padding-right: 20px; &:hover { - background-color: $color-button-success-background-hover; + background-color: var(--color-button-success-background-hover); cursor: pointer; } @@ -205,9 +205,9 @@ button { #lhn { position: fixed; - background-color: $color-highlightBG; + background-color: var(--color-highlightBG); box-sizing: border-box; - border-right-color: $color-borders; + border-right-color: var(--color-borders); border-right-width: 1px; border-style: solid; width: 100%; @@ -230,7 +230,6 @@ button { list-style: none; } - #lhn-content { overflow: auto; display: none; @@ -253,7 +252,6 @@ button { &::-webkit-scrollbar { display: none; } - } &.expanded { @@ -307,7 +305,7 @@ button { .selected { font-weight: bold; - color: $color-text; + color: var(--color-text); } .hide { @@ -338,7 +336,7 @@ button { margin-left: 420px; /* On wide screens, the padding needs to be equal to the view width, minus the content size, minus the lhn size, divided by two. */ - padding: 52px calc((100vw - 1000px - 420px)/2) 0 calc((100vw - 1000px - 420px)/2); + padding: 52px calc((100vw - 1000px - 420px) / 2) 0 calc((100vw - 1000px - 420px) / 2); } ul, @@ -383,7 +381,7 @@ button { // Box shadow is used here because border-radius and border-collapse don't work together. It leads to double borders. // https://stackoverflow.com/questions/628301/the-border-radius-property-and-border-collapsecollapse-dont-mix-how-can-i-use border-style: hidden; - box-shadow: 0 0 0 1px $color-borders; + box-shadow: 0 0 0 1px var(--color-borders); } th:first-child { @@ -405,12 +403,12 @@ button { th, td { padding: 6px 13px; - border: 1px solid $color-borders; + border: 1px solid var(--color-borders); } thead tr th { font-weight: bold; - background-color: $color-highlightBG; + background-color: var(--color-highlightBG); } .img-wrap { @@ -419,7 +417,8 @@ button { flex-wrap: wrap; } - h1, summary { + h1, + summary { font-size: 1.5em; padding: 20px 0 12px 0; } @@ -427,12 +426,12 @@ button { h2 { font-size: 1.125em; font-weight: 500; - font-family: "ExpensifyNewKansas", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNewKansas', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; } h3 { font-size: 1em; - font-family: "ExpensifyNeue", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNeue', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; } h2, @@ -446,25 +445,25 @@ button { margin-bottom: 20px; padding-top: 20px; padding-left: 5%; - border-left: 5px solid #1B5744; + border-left: 5px solid var(--color-button-background-hover); em:before { - content: "\“\a"; + content: '\“\a'; white-space: pre; font-size: 60px; line-height: 1em; - color: #03d47c; + color: var(--color-accent); } p:first-child { font-size: large; - font-family: "ExpensifyNewKansas", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNewKansas', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; opacity: 0.8; } } .selector-container { - background-color: $color-highlightBG; + background-color: var(--color-highlightBG); display: flex; flex-direction: row-reverse; gap: 20px; @@ -472,7 +471,8 @@ button { padding: 20px; margin-bottom: 20px; justify-content: space-between; - * > ol, ul { + * > ol, + ul { padding: 0; } @@ -485,7 +485,7 @@ button { height: 28px; border-radius: 20px; padding: 0px 26px 0px 12px; - color: $color-text; + color: var(--color-text); font-size: 11px; font-weight: 700; text-align: center; @@ -494,11 +494,10 @@ button { @include maxBreakpoint($breakpoint-tablet) { width: 100px; } - } select { - background: url("/assets/images/down.svg") no-repeat right $color-button-background; + background: url('/assets/images/down.svg') no-repeat right var(--color-button-background); background-size: 12px; background-position-x: 85%; appearance: none !important; @@ -510,12 +509,12 @@ button { padding: 12px; margin-bottom: 20px; border-radius: 8px; - background-color: $color-highlightBG; - color: $color-text; + background-color: var(--color-highlightBG); + color: var(--color-text); display: flex; gap: 12px; align-items: center; - + img { height: 16px; width: 16px; @@ -527,21 +526,19 @@ button { } } } - } .link { display: inline; - color: $color-text-supporting; + color: var(--color-text-supporting); cursor: pointer; &:hover { - color: $color-link; + color: var(--color-link); } } .lhn-items { - ol, ul { padding-left: 32px; @@ -565,7 +562,7 @@ button { .selected-article { font-weight: bold; - color: $color-text; + color: var(--color-text); } .home-link { @@ -585,7 +582,6 @@ button { } } - .platform-cards-group { @extend .cards-group; @@ -601,16 +597,16 @@ button { padding: 28px; font-weight: 700; cursor: pointer; - color: $color-text; - background-color: $color-highlightBG; + color: var(--color-text); + background-color: var(--color-highlightBG); &:hover { - background-color: $color-row-hover; + background-color: var(--color-row-hover); } .row { display: flex; - flex-basis:100%; + flex-basis: 100%; } .body { @@ -621,7 +617,7 @@ button { } h3.title { - font-family: "ExpensifyNewKansas", "Helvetica Neue", "Helvetica", Arial, sans-serif; + font-family: 'ExpensifyNewKansas', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; } h3.title, @@ -704,14 +700,14 @@ button { } p.description { - color: $color-text-supporting; + color: var(--color-text-supporting); padding: 20px 0 20px 0; } p.url { padding: 0; font-size: 0.8em; - color: $color-text-supporting; + color: var(--color-text-supporting); } } @@ -733,7 +729,7 @@ button { p.description { padding: 0; - color: $color-text-supporting; + color: var(--color-text-supporting); &.with-min-height { min-height: 68px; @@ -760,7 +756,7 @@ button { padding-top: 0px; } } - h2 { + h2 { padding-bottom: 24px; } p { @@ -818,8 +814,8 @@ button { } h3 { - color: $color-success; - font-family: "ExpensifyNewKansas", "Helvetica Neue", "Helvetica", Arial, sans-serif; + color: var(--color-success); + font-family: 'ExpensifyNewKansas', 'Helvetica Neue', 'Helvetica', Arial, sans-serif; font-size: 17px; font-weight: 500; padding: 0; @@ -836,13 +832,13 @@ button { margin: 0 0 8px; a { - color: $color-text-supporting; + color: var(--color-text-supporting); display: block; padding: 4px 0; word-break: break-word; &:hover { - color: $color-link; + color: var(--color-link); } } } @@ -852,21 +848,21 @@ button { padding-bottom: 20px; a { - color: $color-text-supporting; + color: var(--color-text-supporting); display: inline-block; &:hover { - color: $color-link; + color: var(--color-link); } } } &__fine-print { - color: $color-text-supporting; + color: var(--color-text-supporting); font-size: 10px; a { - color: $color-link; + color: var(--color-link); } } @@ -945,8 +941,8 @@ button { } #platform-tabs > .active { - color: $color-text; - background-color: $color-button-background; + color: var(--color-button-text); + background-color: var(--color-button-success-background); } .hidden { diff --git a/docs/_sass/_search-bar.scss b/docs/_sass/_search-bar.scss index f414d25fc266..e26763d98c09 100644 --- a/docs/_sass/_search-bar.scss +++ b/docs/_sass/_search-bar.scss @@ -6,8 +6,12 @@ margin: auto 0px; } +.gsc-input-box { + border: 0 !important; +} + #sidebar-search { - background-color: $color-appBG; + background-color: var(--color-appBG); width: 375px; position: fixed; display: flex; @@ -61,13 +65,13 @@ /* Full width (cover the whole page) */ height: 100%; - + /* Full height (cover the whole page) */ top: 0; left: 0; right: 0; bottom: 0; - background-color: $color-overlay-background; + background-color: var(--color-overlay); z-index: 1; } @@ -79,22 +83,22 @@ /* This input is in #___gcse_0 search bar */ input#gsc-i-id1.gsc-input { - background-color: $color-appBG; + background-color: var(--color-appBG) !important; padding: 15px 0px 0px !important; pointer-events: auto; - color: #E7ECE9; - font-family: "ExpensifyNeue", "Segoe UI Emoji", "Noto Color Emoji" !important; + color: var(--color-text) !important; + font-family: 'ExpensifyNeue', 'Segoe UI Emoji', 'Noto Color Emoji' !important; } /* These below #gsc-iw-id1, .gsc-input-box & .gsib_a are inner wrapper of search bar input */ #gsc-iw-id1 { - background-color: $color-appBG; - border-bottom: $color-borders 2px solid; + background-color: var(--color-appBG); + border-bottom: var(--color-borders) 2px solid !important; border-bottom-left-radius: 0px; pointer-events: none; &:focus-within { - border-bottom: $color-accent 2px solid; + border-bottom: var(--color-accent) 2px solid !important; } } @@ -106,33 +110,33 @@ input#gsc-i-id1.gsc-input { margin-left: auto; } -.gsst_b, .gsst_a { +.gsst_b, +.gsst_a { padding: 0px !important; } /* This is the close icon on search bar */ .gsib_b .gsst_a .gscb_a { - color: $color-icons; + color: var(--color-icons); padding: 8px 6px 0px 6px !important; pointer-events: auto; &:hover { - color: $color-text; + color: var(--color-text); } } /* This is to manage hover on parent close icon and make it the same effect on close icon */ .gsst_a:hover { - .gscb_a { - color: $color-text !important; + color: var(--color-text) !important; } } /* Manage Google Search label animation */ -input#gsc-i-id1:focus+label.search-label, -input#gsc-i-id1:valid+label.search-label, -input#gsc-i-id1:active+label.search-label { - transform: translateY(-100%) scale(0.80); +input#gsc-i-id1:focus + label.search-label, +input#gsc-i-id1:valid + label.search-label, +input#gsc-i-id1:active + label.search-label { + transform: translateY(-100%) scale(0.8); } label.search-label { @@ -140,11 +144,11 @@ label.search-label { position: absolute; margin-top: -20px; font-size: 15px; - font-family: "ExpensifyNeue", "Segoe UI Emoji", "Noto Color Emoji"; + font-family: 'ExpensifyNeue', 'Segoe UI Emoji', 'Noto Color Emoji'; transform: translateY(-50%); left: 20px; pointer-events: none; - color: $color-text-supporting; + color: var(--color-text-supporting); transform-origin: left top; user-select: none; transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1), color 150ms cubic-bezier(0.4, 0, 0.2, 1), top 500ms; @@ -160,9 +164,14 @@ label.search-label { } .gsc-control-cse { - background-color: $color-appBG; - border: $color-appBG; - font-family: "ExpensifyNeue", "Helvetica Neue", "Helvetica", Arial, sans-serif !important; + background-color: var(--color-appBG) !important; + border: var(--color-appBG) !important; + font-family: 'ExpensifyNeue', 'Helvetica Neue', 'Helvetica', Arial, sans-serif !important; +} + +.gsc-webResult.gsc-result { + border-color: var(--color-appBG) !important; + background-color: var(--color-appBG) !important; } /* Hide the scrollbar */ @@ -180,18 +189,20 @@ label.search-label { margin-left: 15px; margin-right: 20px; border-radius: 25px; - background-color: $color-button-success-background; + background-color: var(--color-button-success-background); + border-color: var(--color-appBG) !important; cursor: pointer; width: 40px; height: 40px; } -.gsc-search-button.gsc-search-button-v2:hover { - background-color: $color-button-success-background-hover; +.gsc-search-button.gsc-search-button-v2:hover, +.gsc-search-button.gsc-search-button-v2:focus { + background-color: var(--color-button-success-background-hover); } .gsc-search-button.gsc-search-button-v2 svg { - fill: $color-text; + fill: var(--color-button-text); height: auto; width: auto; } @@ -205,21 +216,20 @@ label.search-label { border-bottom: none; } - /* Change Font the Google Search result */ .gsc-control-cse .gsc-table-result { - font-family: "ExpensifyNeue", "Helvetica Neue", "Helvetica", Arial, sans-serif !important; + font-family: 'ExpensifyNeue', 'Helvetica Neue', 'Helvetica', Arial, sans-serif !important; } /* Change Font result Paragraph color */ -.gsc-results .gs-webResult:not(.gs-no-results-result):not(.gs-error-result) .gs-snippet, .gs-fileFormatType { - color: $color-text-supporting; +.gsc-results .gs-webResult:not(.gs-no-results-result):not(.gs-error-result) .gs-snippet, +.gs-fileFormatType { + color: var(--color-text-supporting); } - /* Change the color of the Google Search Suggestion font */ .gs-spelling.gs-result { - color: $color-text; + color: var(--color-text); } /* Pagination related style */ @@ -234,37 +244,36 @@ label.search-label { border-radius: 25px; display: inline-block; line-height: 2.5; - background-color: $color-accent; + background-color: var(--color-accent); font-weight: bold; font-size: 11px; } - /* Change the color & background of Google Search Pagination */ .gsc-cursor-next-page, .gsc-cursor-final-page { - color: $color-text; - background-color: $color-appBG; + color: var(--color-text); + background-color: var(--color-appBG); } /* Change the color & background of Google Search Current Page */ .gsc-resultsbox-visible .gsc-results .gsc-cursor-box .gsc-cursor-page.gsc-cursor-current-page { - background-color: $color-accent; - color: $color-text; + background-color: var(--color-accent); + color: var(--color-text); &:hover { text-decoration: none; - background-color: $color-accent; + background-color: var(--color-accent); } } /* Change the color & background of Google Search of Other Page */ .gsc-resultsbox-visible .gsc-results .gsc-cursor-box .gsc-cursor-page { - background-color: $color-button-background; - color: $color-text; + background-color: var(--color-button-background); + color: var(--color-text); &:hover { - background-color: $color-button-background-hover; + background-color: var(--color-button-background-hover); text-decoration: none; } } diff --git a/docs/articles/expensify-classic/copilots-and-delegates/Delegate-when-out-of-office.md b/docs/articles/expensify-classic/copilots-and-delegates/Delegate-when-out-of-office.md new file mode 100644 index 000000000000..758d36b89054 --- /dev/null +++ b/docs/articles/expensify-classic/copilots-and-delegates/Delegate-when-out-of-office.md @@ -0,0 +1,47 @@ +--- +title: Delegate when out of office +description: Assign a vacation delegate to act on your behalf or on behalf of another employee +--- + +When you're out of office or on vacation, you can assign a Vacation Delegate to manage your reports while you're away. Domain Admins can also assign delegates for other members of their domain. + +A Vacation Delegate approves expense reports on behalf of another workspace member when needed. Once they are assigned, any reports sent to the member for approval will immediately start going to their delegate. Then when the member is ready to take over their reports again, they’ll be able to disable the delegate. + +Expensify keeps a detailed audit trail to show exactly when a delegate stepped in to approve reports on someone else's behalf and what actions they took on the report. + +# Assign a delegate for yourself + +1. Hover over Settings and click **Account**. +2. Under Account Details, scroll down to the Vacation Delegate section. +3. Enter the email address or phone number for the person you want to assign as your delegate. +4. Click **Set Delegate**. + +Any reports that usually come to you will now go to your delegate instead. You can see every action your Vacation Delegate takes on your behalf for each report under the report history and comments. + +## Disable a delegate + +When you’re ready to take over your reports again, remove the delegate by clicking the Return from Vacation banner at the top of your account. + +# Assign a delegate for an employee + +{% include info.html %} +You must be a Domain Admin to complete this process. +{% include end-info.html %} + +1. Hover over Settings and click **Domains**. +2. Click the name of the domain. +3. Click the **Domain Members** tab on the left. +4. Find the member you want to assign a delegate for by using the filters to filter by their name, or enter their name into the “Find Members” search box. +5. Click **Edit Settings** next to the member. +6. Enter the delegate's phone number or email address into the Vacation Delegate field. +7. Click **Save**. + +# FAQs + +**Why can’t my Vacation Delegate reimburse reports that they approve?** + +If your Vacation Delegate also needs to reimburse reports on your behalf while you’re away, they’ll also need access to the reimbursement account. If they do not have access to the reimbursement account used on your workspace, they won’t have the option to reimburse reports, even as your Vacation Delegate. + +**What if my Vacation Delegate is also on vacation?** + +Your delegate can also pick their own Vacation Delegate. This way, expense reports continue to get approved even if multiple members are away at the same time. diff --git a/docs/articles/expensify-classic/copilots-and-delegates/Vacation-Delegate.md b/docs/articles/expensify-classic/copilots-and-delegates/Vacation-Delegate.md deleted file mode 100644 index 4727b1c4a38b..000000000000 --- a/docs/articles/expensify-classic/copilots-and-delegates/Vacation-Delegate.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Vacation Delegate -description: In Expensify, a vacation delegate is someone you choose to act on your behalf when you're on vacation or taking personal time off. ---- - -# Overview - -A delegate is someone who can handle approving expense reports for you, which is especially useful when you're out of the office! - -In Expensify, a **Vacation Delegate** is someone you choose to act on your behalf when you're on vacation or taking personal time off. They will approve expense reports just like you would, and everything moves forward as usual afterward. - -The system keeps a detailed audit trail, showing exactly when your delegate stepped in to approve a report for you. And if your delegate also goes on vacation, they can have their own delegate, so reports keep getting approved. - -By using this feature, you ensure that all reports get the approvals they need, even when you're not around. - -# How to use Vacation Delegate - -If you're planning to take some time off, you can use the **Vacation Delegate** feature to assign someone to approve expense reports for you. The reports will continue on their usual path as if you had approved them yourself. - -## Set a Vacation Delegate for yourself - -1. Go to the Expensify website (note: you can't do this from the mobile app). -2. Navigate to **Settings > Your Account > Account Details** and scroll down to find **Vacation Delegate**. -3. Enter the email address of the person you're designating as your delegate and click **Set Delegate**. - -Voila! You've set a vacation delegate. Any reports that usually come to you will now go to your delegate instead. When you return, you can easily remove the delegate by clicking a link at the top of the Expensify homepage. - -## Setting a Vacation Delegate as a Domain Admin - -1. Head to **Settings > Domains > [Your Domain Name] > Domain Members > Edit Settings** -2. Enter the delegate's email address and click **Save.** - -Your delegate's actions will be noted in the history and comments of each report they approve, so you can keep track of what happened while you were away. - -# Deep Dive - -## An audit trail of delegate actions - -The system records every action your vacation delegate takes on your behalf in the **Report History and Comments**. So, you can see when they approved an expense report for you. - -{% include faq-begin.md %} - -## Why can't my Vacation Delegate reimburse reports that they approve? - -If your **Vacation Delegate** also needs to reimburse reports on your behalf whilst you're away, they'll also need access to the reimbursement account. - -If they do not have access to the reimbursement account used on your workspace, they won’t have the option to reimburse reports, even as your **Vacation Delegate**. - -## What if my Vacation Delegate is also on vacation? - -Don't worry, your delegate can also pick their own **Vacation Delegate**. This way, expense reports continue to get approved even if multiple people are away. - -{% include faq-end.md %} diff --git a/docs/articles/expensify-classic/domains/Add-Domain-Members-and-Admins.md b/docs/articles/expensify-classic/domains/Add-Domain-Members-and-Admins.md new file mode 100644 index 000000000000..03dd3d722d82 --- /dev/null +++ b/docs/articles/expensify-classic/domains/Add-Domain-Members-and-Admins.md @@ -0,0 +1,54 @@ +--- +title: Add Domain Members and Admins +description: Add members and admins to a domain +--- +
+ +{% include info.html %} +To add members to your domain, your domain must be verified. Once a domain is verified, only Domain Admins will have access to the domain’s settings and member information. +{% include end-info.html %} + +Your domain can include members and admins. + - **Domain Member**: Domain Members are associated with a specific domain and managed by the rules configured by the Domain Admins. They cannot see or modify any of the domain settings. A Domain Member must have an email address under the domain name (for example, an email address @yourcompany.com) listed as their primary or secondary email address. +- **Domain Admin**: Has full authority over the domain settings and can add or modify members, admin, groups, rules, and company credit cards. Domain Admins are not required to have an email address connected to the domain. + +# Add Domain Member + +There are two ways to add a member to a domain: +- The member can be automatically added to the domain if they sign up or are added to Expensify using an email address that contains their domain name (for example, an email address @yourcompany.com). +- A Domain Admin can manually add a new member to the domain. + +## Automatic Domain Member signup + +- **New Expensify members**: By creating their account using their domain email address (like yourname@yourcompany.com), they will be automatically added as a member of the domain. +- **Existing Expensify members**: Members that already have an Expensify account can add their domain email address (like yourname@yourcompany.com) as their secondary or primary email address to be automatically added as a member of the domain once they verify their email address. + +{% include info.html %} +The member’s primary email address will be the one that is listed under the domain, even if their secondary email address is the one that matches the domain. +{% include end-info.html %} + +Once the member verifies their email address, all Domain Admins will be notified and the employee will be added to the default group. + +## Manually add a Domain Member + +1. Hover over Settings, then click **Domains**. +2. Click the name of the domain. +3. Click the **Domain Members** tab on the left. +4. Under the Domain Members section, enter the first part of the member’s email address and click **Invite**. + +{% include info.html %} +This can be any email address—it does not have to be an email address under the domain. If someone who is not a Domain Admin invites a new member to a workspace, that member must validate their account via email before they will have access to it. +{% include end-info.html %} + +# Add Domain Admin + +1. Hover over Settings, then click **Domains**. +2. Click the name of the domain. +3. Click the **Domain Admins** tab on the left. +4. Under the Domain Admins section, enter the phone number or email address of the person you’re inviting as a domain admin and click **Add Admin**. + +{% include info.html %} +This can be any email address—it does not have to be an email address under the domain. +{% include end-info.html %} + +
diff --git a/docs/articles/expensify-classic/domains/Switch-Domain-Member-to-Admin.md b/docs/articles/expensify-classic/domains/Switch-Domain-Member-to-Admin.md new file mode 100644 index 000000000000..8a01a3170903 --- /dev/null +++ b/docs/articles/expensify-classic/domains/Switch-Domain-Member-to-Admin.md @@ -0,0 +1,14 @@ +--- +title: Switch Domain Member to Admin +description: Change a Domain Member's role to Admin +--- +
+ +A Domain Admin can change a current member of your domain to a Domain Admin by completing the following steps: + +1. Hover over Settings, then click **Domains**. +2. Click the name of the domain. +3. Click the **Domain Admins** tab on the left. +4. Under the Domain Admins section, enter the member’s phone number or email address and click **Add Admin**. + +
diff --git a/docs/articles/expensify-classic/expenses/Add-expenses-to-a-report.md b/docs/articles/expensify-classic/expenses/Add-expenses-to-a-report.md new file mode 100644 index 000000000000..96427a60d87f --- /dev/null +++ b/docs/articles/expensify-classic/expenses/Add-expenses-to-a-report.md @@ -0,0 +1,18 @@ +--- +title: Add expenses to a report +description: Add expenses to a report to submit them for approval +--- +
+ +To submit expenses for approval, they must be added to a report. + +1. Click the **Expenses** tab. +2. Find the expenses you want to add to the report by searching through the table of expenses and/or using the sort filters. +3. Select the expenses by checking the box to the left of each expense or selecting them all. +4. Click **Add to Report** in the right corner and select either: + - **Auto-Report**: Automatically adds the expenses to an open report, or creates a new report if there are no open reports + - **New Report**: Creates a new report for the expenses + - **None**: Ensures none of the selected expenses are attached to a report (as long as the report has not already been submitted) + - **Existing Report**: Adds the expenses to the selected report + +
diff --git a/docs/articles/expensify-classic/expenses/Distance-Tracking.md b/docs/articles/expensify-classic/expenses/Distance-Tracking.md deleted file mode 100644 index c0d8956f71ac..000000000000 --- a/docs/articles/expensify-classic/expenses/Distance-Tracking.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Distance Tracking in Expensify -description: Learn how distance tracking works in Expensify! ---- - -# Overview - -Expensify provides a convenient feature for tracking your mileage-related expenses. You'll find all the essential information to begin logging your trips below. - -# How to Use Distance Tracking -## Mobile App - -First, you’ll want to click the **+** in the top right corner. - -If you select **Manually Create**, you’ll be prompted to enter your mileage, select a rate, and code the expense before clicking **Save**. - - ![Click manually create or odometer to create a distance request.](https://help.expensify.com/assets/images/ExpensifyHelp_CreateExpense_Mobile.png){:width="100%"} - -If you select **Manually Create**: - - Enter your mileage. - - Select a rate. - - Code the expense. - - Click **Save**. - -![Enter your mileage, rate, code the expense, and click save.](https://help.expensify.com/assets/images/ExpensifyHelp_ManualDistance_Mobile.png){:width="100%"} - -If you select **Odometer**: - - Enter your vehicle’s mileage reading before and after your trip. - - Select your rate. - - Code the expense. - - Click **Save**. - -![Etner your mileage readings, your rate, code the expense, and click save.](https://help.expensify.com/assets/images/ExpensifyHelp_Odometer_Mobile.png){:width="100%"} - -The **Start GPS** option also exists on the mobile app. However, we’ve learned that most customers prefer to track their mileage after their trips (thus not needing to hit that start button!) - -We’ve temporarily paused the development of GPS mileage tracking in the mobile app, and we recommend you use one of the above options instead! - - -## Web - -Navigate to the **Expenses** page, click **New Expense**, and review the two **Distance** options. - -![Select manually create or create from map to create a new distance request.](https://help.expensify.com/assets/images/ExpensifyHelp_CreateExpense.png){:width="100%"} - -If you select **Manually Create**: - - Enter the number of miles for your trip. - - Mileage rate is automatically selected based on your history, or manually select it if it's your first time. - - Complete any other applicable coding fields. - - Click **Save**. - -![Enter the number of miles, select your rate, code the expense, and click save.](https://help.expensify.com/assets/images/ExpensifyHelp_ManualDistance.png){:width="100%"} - -For **Create from Map** expenses: - - Add your start and end location, and the distance will be calculated. - - You can also click **Add Destination** for multiple stops. - - Leave **Create Receipt** selected if you want a map receipt generated. - - Click **Save**. - -![Enter your start and end locations, and click save.](https://help.expensify.com/assets/images/ExpensifyHelp_ManualDistanceMap.png){:width="100%"} - -Once you click **Save**, review the details from your map selection. - - Select your rate. - - Enter any other applicable coding. - - Click **Save**. - -![Select your rate, code the expense, and click save.](https://help.expensify.com/assets/images/ExpensifyHelp_ManualDistanceConfirm.png){:width="100%"} - -# Mileage Tracking FAQs -## **How can I change the rate of my mileage expenses?** -You can change the rate by going to Settings > Workspaces > [Your Workspace] > Expenses > Distance > Add a Mileage Rate. -If you submit mileage expenses on a group workspace, only workspace admins can do this. - -## **Do you plan to add the "Create from Map" option to the mobile app or "Odometer" option to web?** -Not now, but if that changes, you'll be the first to know! - -## **Will you restart maintenance on the mobile app's GPS option anytime soon?** -Not now, but if that changes, you'll be the first to know! - -## **Does Expensify automatically update IRS Mileage rates?** - We never automatically update mileage rates in Expensify because different companies want the new rates to become effective on different dates. diff --git a/docs/articles/expensify-classic/expenses/Track-mileage-expenses.md b/docs/articles/expensify-classic/expenses/Track-mileage-expenses.md new file mode 100644 index 000000000000..e8b9ab0eac75 --- /dev/null +++ b/docs/articles/expensify-classic/expenses/Track-mileage-expenses.md @@ -0,0 +1,66 @@ +--- +title: Track mileage expenses +description: Add mileage-related expenses +--- + +
+ +You can track your mileage-related expenses by logging your trips in Expensify. You have a couple of different options for logging distance: + +- Web app: + - **Manually create**: Manually enter the number of miles for the trip + - **Create from map**: Automatically determine the trip distance based on the start and end location. +- Mobile app: + - **Manually create**: Manually enter the miles for the trip and your mileage rate + - **Odometer**: Enter your odometer reading before and after the trip + - **Start GPS**: Currently under development and unavailable for use. + +{% include info.html %} +When adding a distance expense, the rates available are determined by the rates set in your workspace rate settings. To update these rates or add a new rate, you must be a Workspace Admin. +{% include end-info.html %} + +{% include selector.html values="desktop, mobile" %} + +{% include option.html value="desktop" %} + +1. Click the **Expenses** tab. +2. Click **New Expense**. +3. Select the expense type. + - **Manually create**: + - Enter the number of miles for the trip. + - Select your rate. + - If desired, select the category, add a description, or select a report to add the expense to. + - Click **Save**. + - **Create from map**: + - Add your start location as point A. + - Add your end location as point B. + - If applicable, click **Add Destination** to add additional stops. + - To generate a map receipt, leave the Create Receipt checkbox selected. + - Click **Save**. + - Select your rate. + - If desired, select the category, add a description, or select a report to add the expense to. + - Click **Save**. + +{% include end-option.html %} + +{% include option.html value="mobile" %} + +1. Click the + icon in the top right corner. +2. Under the Distance section, select the expense type. + - **Manually create**: + - Enter your mileage. + - Select your rate. + - If desired, click **More Options** to select the category, add a description, or select a report to add the expense to. + - Click **Save**. + - **Odometer**: + - Enter your vehicle’s odometer reading before the trip. + - Enter your vehicle’s odometer reading after the trip. + - Select your rate. + - If desired, click **More Options** to select the category, add a description, or select a report to add the expense to. + - Click **Save**. +{% include end-option.html %} + +{% include end-selector.html %} + +
+ diff --git a/docs/articles/expensify-classic/expenses/reports/Create-A-Report.md b/docs/articles/expensify-classic/expenses/reports/Create-A-Report.md index 88ec2b730d1e..e8dfdbf44bcb 100644 --- a/docs/articles/expensify-classic/expenses/reports/Create-A-Report.md +++ b/docs/articles/expensify-classic/expenses/reports/Create-A-Report.md @@ -91,7 +91,7 @@ There are three ways you can change the report layout under the Details section # How to retract your report (Undo Submit) -As long as the report is still in a Processing state, you can retract this submission to put the report back to Draft status to make corrections and re-submit. +You can edit expenses on a report in a **Processing** state so long as it hasn't been approved yet. If a report has been through a level of approval and is still in the **Processing** state, you can retract this submission to put the report back to Draft status to make corrections and re-submit. To retract a **Processing** report on the web app, click the Undo Submit button at the upper left-hand corner of the report. diff --git a/docs/articles/expensify-classic/integrations/HR-integrations/Workday.md b/docs/articles/expensify-classic/integrations/HR-integrations/Workday.md index ecdea4699ee0..47e7a5b5382a 100644 --- a/docs/articles/expensify-classic/integrations/HR-integrations/Workday.md +++ b/docs/articles/expensify-classic/integrations/HR-integrations/Workday.md @@ -34,7 +34,7 @@ In order to complete the steps below, you'll need a Workday System Administrator 4. Search and select "security group membership and access". 5. Search for the security group you just created. 6. Click the ellipsis, then **Security Group > Maintain Domain Permissions for Security Group**. -7. Under **Integration Permissions**, add "External Account Provisioning" to **Domain Security Workspaces permitting Put access** and "Worker Data: Workers" to **Domain Security Workspaces permitting Get access**. +7. Head to Integration Permissions and add **Get access** for “External Account Provisioning” and “Worker Data: Workers” under Domain Security Workspaces. 8. Click **OK** and **Done**. 9. Search **Activate Pending Security Workspace Changes** and complete the task for activating the security workspace change, adding a comment if required and checking the **Confirmed** check-box. diff --git a/docs/articles/expensify-classic/settings/Close-Account.md b/docs/articles/expensify-classic/settings/Close-Account.md deleted file mode 100644 index 9b1e886fc94a..000000000000 --- a/docs/articles/expensify-classic/settings/Close-Account.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Close Account -description: Close Account ---- -# Overview - -Here is a walk through of how to close an Expensify account through the website or mobile app. - -# How to close your account -On the Web: - -1. Go to **Settings** in the left hand menu. Click **Account**. -2. Click “Close Account” -3. Follow the prompts to verify your email or phone number. -4. Your account will be closed, and all data will be deleted.* - -![Close Account via Website]({{site.url}}/assets/images/ExpensifyHelp_CloseAccount_Desktop.png){:width="100%"} - -On the Mobile App: - -Open the app and tap the three horizontal lines in the upper left corner. -Select Settings from the menu. -Look for the "Close Account" option in the "Others" section. (If you don’t see this option, you have a Domain Controlled account and will need to ask your Domain Admin to delete your account.) -Complete the verification process using your email or phone number. -Your account will be closed, and all data will be deleted.* - -![Close Account on Mobile Application]({{site.url}}/assets/images/ExpensifyHelp_CloseAccount_Mobile.png){:width="100%"} - -These instructions may vary depending on the specific device you are using, so be sure to follow the steps as they appear on your screen. - -*Note: Transactions shared with other accounts will still be visible to those accounts. (Example: A report submitted to your company and reimbursed will not be deleted from your company’s account.) Additionally, we are required to retain certain records of transactions in compliance with laws in various jurisdictions. - -# How to reopen your account - -If your Expensify account is closed and not associated with a verified domain, you can reopen it with the following steps: - -1. Visit [expensify.com](https://www.expensify.com/). -2. Attempt to sign in using your email address or phone number associated with the closed account. -3. After entering your user name, you will see a prompt to reopen your account. -4. Click on **Reopen Account**. -5. A magic link will be sent to your email address. -6. Access your email and click on the magic link. This link will take you to Expensify and reopen your account. -7. Follow the prompts to create a new password associated with your account. -8. Your account is now reopened. Any previously approved expense data will still be visible in the account. - -Note: Reports submitted and closed on an Individual workspace will not be retained since they have not been approved or shared with anyone else in Expensify. - -That's it! Your account is successfully reopened, and you can access your historical data that was shared with other accounts. Remember to recreate any workspaces and adjust settings if needed. - -# How to Reopen a Domain-controlled account -Once an account has been **Closed** by a Domain Admin, it can be reopened by any Domain Admin on that domain. - -The Domain Admin will simply need to invite the previously closed account in the same manner that new accounts are invited to the Domain. The user will receive a magic link to their email account which they can use to Reopen the account. - -# How to retain a free account to keep historical expenses -If you no longer need a group workspace or have a more advanced workspace than necessary in Expensify, and you want to downgrade while retaining your historical data, here's what you should do: - -1. If you're part of a group workspace, request the Workspace Admin to remove you, or if you own the workspace, delete it to downgrade to a free version. -2. Once you've removed or been removed from a workspace, start using your free Expensify account. Your submitted expenses will still be saved, allowing you to access the historical data. -3. Domain Admins in the company will still retain access to approved and reimbursed expenses. -4. To keep your data, avoid closing your account. Account closures are irreversible and will result in the deletion of all your unapproved data. - -# Deep Dive - -## I’m unable to close my account - -If you're encountering an error message while trying to close your Expensify account, it's important to pinpoint the specific error. Encountering an error when trying to close your account is typically only experienced if the account has been an admin on a company’s Expensify workspace. (Especially if the account was involved in responsibilities like reimbursing employees or exporting expense reports.) - -In order to avoid users accidentally creating issues for their company, Expensify prevents account closure if you still have any individual responsibilities related to a Workspace within the platform. To successfully close your account, you need to ensure that your workspace no longer relies on your account to operate. - -Here are the reasons why you might encounter an error when trying to close your Expensify account, along with the actions required to address each of these issues: - -- **Account Under a Validated Domain**: If your account is associated with a validated domain, only a Domain Admin can close it. You can find this option in your Domain Admin's settings under Settings > Domains > Domain Members. Afterward, if you have a secondary personal login, you can delete it by following the instructions mentioned above. -- **Sole Domain Admin for Your Company**: If you are the only Domain Admin for your company's domain, you must appoint another Domain Admin before you can close your account. This is to avoid accidentally prohibiting your entire company from using Expensify. You can do this by going to Settings > Domains > [Domain Name] > Domain Admins and making the necessary changes, or you can reset the entire domain. -- **Workspace Billing Owner with an Annual Subscription**: If you are the Workspace Billing Owner with an Annual Subscription, you need to downgrade from the Annual subscription before closing the account. Alternatively, you can have another user take over billing for your workspaces. -- **Ownership of a Company Workspace or Outstanding Balance**: If you own a company workspace or there is an outstanding balance owed to Expensify, you must take one of the following actions before closing your account: - - - Make the payment for the outstanding balance. - - Have another user take over billing for the workspace. - - Request a refund for your initial bill. - - Delete the workspace. - -- **Preferred Exporter for Your Workspace Integration**: If you are the "Preferred Exporter" for a workspace Integration, you must update the Preferred Exporter before closing your account. You can do this by navigating to **Settings** > **Workspaces** > **Group** > [Workspace name] > **Connections** > **Configure** and selecting any Workspace Admin from the dropdown menu as the Preferred Exporter. -- **Verified Business Account with Outstanding Balance or Locked Status**: If you have a Verified Business Account with an outstanding balance or if the account is locked, you should wait for all payments to settle or unlock the account. To settle the amount owed, go to **Settings** > **Account** > **Payments** > **Bank Accounts** and take the necessary steps. - -## Validate the account to close it - -Sometimes, you may find yourself with an Expensify account that you don't need. This could be due to various reasons like a company inviting you for reimbursement, a vendor inviting you to pay, or a mistaken sign-up. - -In such cases, you have two options: - -**Option 1**: Retain the Account for Future Use -You can keep the Expensify account just in case you need it later. - -**Option 2**: Close the Account - -Start by verifying your email or phone number - -Before closing the account, you need to verify that you have access to the email or phone number associated with it. This ensures that only you can close the account. - -Here's how to do it: - -1. Go to [www.expensify.com](http://www.expensify.com/). -2. Enter your email address or phone number (whichever is associated with the unwanted account). -3. Click the **Resend Link** button. -4. Check your Home Page for the most recent email with the subject line "Please validate your Expensify login." Click the link provided in the email to validate your email address. - - If it's an account linked to a phone number, tap the link sent to your phone. -5. After clicking the validation link, you'll be directed to an Expensify Home Page. -6. Navigate to **Settings** > **Account** > **Account Details** > **Close Account**. -7. Click the **Close My Account** button. - - Re-enter the email address or phone number of the account when prompted. - - Check the box that says, "I understand all of my unsubmitted expense data will be deleted." - - Click the **Close My Account** button. - -By following these steps, you can easily verify your email or phone number and close an unwanted Expensify account. - -{% include faq-begin.md %} - -## What should I do if I'm not directed to my account when clicking the validate option from my phone or email? -It's possible your browser has blocked this, either because of some existing cache or extension. In this case, you should follow the Reset Password flow to reset the password and manually gain access with the new password, along with your email address. - -## Why don't I see the Close Account option? -It's possible your account is on a managed company domain. In this case, only the admins from that company can close it. - -{% include faq-end.md %} diff --git a/docs/articles/expensify-classic/settings/Close-or-reopen-account.md b/docs/articles/expensify-classic/settings/Close-or-reopen-account.md new file mode 100644 index 000000000000..7ef7da7137c5 --- /dev/null +++ b/docs/articles/expensify-classic/settings/Close-or-reopen-account.md @@ -0,0 +1,75 @@ +--- +title: Close or reopen account +description: Close or reopen an Expensify account +--- +
+ +# Close an account + +Closing your account will delete the data associated with the account. However, transactions shared with other accounts, including approved and reimbursed company expenses, will still be visible under those accounts. We may also be required to retain certain transaction records in compliance with laws in various jurisdictions. + +{% include info.html %} +If you no longer need a group workspace but want to keep your historical data, you can ask the Workspace Admin to remove you from the workspace, or you can delete the workspace if you own it. Once removed from the workspace, you will automatically be downgraded to a free account and will continue to have access to your Expensify account and all of your data. +{% include end-info.html %} + +{% include selector.html values="desktop, mobile" %} + +{% include option.html value="desktop" %} +1. Hover over Settings, then click **Account**. +2. Scroll down to the bottom of the page and click **Close Account**. + +{% include info.html %} +If you don’t see this option, you have a domain-controlled account and will need to ask your Domain Admin to delete your account. +{% include end-info.html %} + +3. Use your phone or email to confirm the changes. + +{% include end-option.html %} + +{% include option.html value="mobile" %} +These instructions may vary based on your device. + +1. Tap the menu in the top left. +2. Tap **Settings**. +3. Scroll down to the Others section and tap **Close Account**. + +{% include info.html %} +If you don’t see this option, you have a domain-controlled account and will need to ask your Domain Admin to delete your account. +{% include end-info.html %} + +4. Use your phone or email to confirm the changes. +{% include end-option.html %} + +{% include end-selector.html %} + +# Reopen a closed account + +If you closed your own account, follow the directions below to reopen it. However, if your Expensify account was closed by a Domain Admin, a Domain Admin for that domain must invite the closed account as a new member. + +1. Sign in to Expensify using the email address or phone number associated with the closed account. +2. Click **Reopen Account**. +3. Open your email and click the link from Expensify. + +Your account is now reopened. You can recreate any necessary workspaces, adjust your settings, and access any historical data you previously shared with other accounts. + +{% include info.html %} +Any data or reports that weren’t shared were permanently deleted when the account was closed. +{% include end-info.html %} + +# FAQs + +**I’m unable to close my account.** + +If your account has an outstanding balance or if you have been assigned a role under a company’s Expensify workspace, you may encounter an error message during the account closure process, or the Close Account button may not be available. Here are the steps to follow for each scenario: + +- **Account Under a Validated Domain**: A Domain Admin must remove your account from the domain. Then you will be able to successfully close your account. +- **Sole Domain Admin**: If you are the only Domain Admin for a company’s domain, you must assign a new Domain Admin before you can close your account. +- **Workspace Billing Owner with an annual subscription**: You must downgrade from the annual subscription before closing the account. Alternatively, you can have another user take over billing for your workspaces. +- **Company Workspace Owner**: You must assign a new workspace owner before you can close your account. +- **Account has an outstanding balance**: You must make a payment to resolve the outstanding balance before you can close your account. +- **Preferred Exporter for a workspace integration**: You must assign a new Preferred Exporter before closing your account. +- **Verified Business Account that is locked**: You must unlock the account. +- **Verified Business Account that has an outstanding balance**: You must make a payment to settle any outstanding balances before the account can be closed. +- **Unverified account**: You must first verify your account before it can be closed. + +
diff --git a/docs/articles/expensify-classic/settings/Copilot.md b/docs/articles/expensify-classic/settings/Copilot.md deleted file mode 100644 index 31bc0eff60e6..000000000000 --- a/docs/articles/expensify-classic/settings/Copilot.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Copilot -description: Safely delegate tasks without sharing login information. ---- - -# About -The Copilot feature allows you to safely delegate tasks without sharing login information. Your chosen user can access your account through their own Expensify account, with customizable permissions to manage expenses, create reports, and more. This can even be extended to users outside your policy or domain. - -# How-to -# How to add a Copilot -1. Log into the Expensify desktop website. -2. Navigate to *Settings > Account > Account Details > _Copilot: Delegated Access_*. -3. Enter the email address or phone number of your Copilot and select whether you want to give them Full Access or the ability to Submit Only. - - *Full Access Copilot*: Your Copilot will have full access to your account. Nearly every action you can do and everything you can see in your account will also be available to your Copilot. They *will not* have the ability to add or remove other Copilots from your account. - - *Submit Only Copilot*: Your Copilot will have the same limitations as a Full Access Copilot, with the added restriction of not being able to approve reports on your behalf. -4. Click Invite Copilot. - -If your Copilot already has an Expensify account, they will get an email notifying them that they can now access your account from within their account as well. -If they do not already have an Expensify account, they will be provided with a link to create one. Once they have created their Expensify account, they will be able to access your account from within their own account. - -# How to use Copilot -A designated copilot can access another account via the Expensify website or the mobile app. - -## How to switch to Copilot mode (on the Expensify website): -1. Click your profile icon in the upper left side of the page. -2. In the “Copilot Access” section of the dropdown, choose the account you wish to access. -3. When you Copilot into someone else’s account, the Expensify header will change color and an airplane icon will appear. -4. You can return to your own account at any time by accessing the user menu and choosing “Return to your account”. - -## How to switch to Copilot Mode (on the mobile app): -1. Tap on the menu icon on the top left-hand side of the screen, then tap your profile icon. -2. Tap “Switch to Copilot Mode”, then choose the account you wish to access. -3. You can return to your own account at any time by accessing the user menu and choosing “Return to your account”. - -# How to remove a Copilot -If you ever need to remove a Copilot, you can do so by following the below steps: -1. Log into the Expensify desktop website -2. Navigate to *Settings > Your Account > Account Details > _Copilot: Delegated Access_* -3. Click the red X next to the Copilot you'd like to remove - - -# Deep Dive -## Copilot Permissions -A Copilot can do the following actions in your account: -- Prepare expenses on your behalf -- Approve and reimburse others' expenses on your behalf (Note: this applies only to **Full Access** Copilots) -- View and make changes to your account/domain/policy settings -- View all expenses you can see within your own account - -## Copilot restrictions -A Copilot cannot do the following actions in your account: -- Change or reset your password -- Add/remove other Copilots - -## Forwarding receipts to receipts@expensify.com as a Copilot -To ensure a receipt is routed to the Expensify account in which you are a copilot rather than your own you’ll need to do the following: -1. Forward the email to receipts@expensify.com -2. Put the email of the account in which you are a copilot in the subject line -3. Send - - -{% include faq-begin.md %} -## Can a Copilot's Secondary Login be used to forward receipts? -Yes! A Copilot can use any of the email addresses tied to their account to forward receipts into the account of the person they're assisting. - -## I'm in Copilot mode for an account; Can I add another Copilot to that account on their behalf? -No, only the original account holder can add another Copilot to the account. -## Is there a restriction on the number of Copilots I can have or the number of users for whom I can act as a Copilot? -There is no limit! You can have as many Copilots as you like, and you can be a Copilot for as many users as you need. - -{% include faq-end.md %} diff --git a/docs/articles/expensify-classic/workspaces/Change-member-workspace-roles.md b/docs/articles/expensify-classic/workspaces/Change-member-workspace-roles.md new file mode 100644 index 000000000000..29fbc8b46323 --- /dev/null +++ b/docs/articles/expensify-classic/workspaces/Change-member-workspace-roles.md @@ -0,0 +1,26 @@ +--- +title: Change member workspace roles +description: Update a member's role for a workspace +--- +
+ +To change the roles and permissions for members of your workspace, + +1. Hover over Settings, then click **Workspaces**. +2. Click the **Group** tab on the left. +3. Click the desired workspace name. +4. Click the **Members** tab on the left. +5. Click the Settings icon next to the desired member. +6. Select a new role for the member. + +| | Employee | Auditor | Workspace Admin | +|---------------------------|----------------------------------|---------|-----------------| +| Submit reports | Yes | Yes | Yes | +| Comment on reports | Yes | Yes | Yes | +| Approve workspace reports | Only reports submitted to them | Yes | Yes | +| Edit workspace settings | No | No | Yes | + +7. If your workspace uses Advanced Approvals, select an “Approves to.” This determines who the member’s reports must be approved by, if applicable. If “no one” is selected, then any one with the Auditor or Workspace Admin role can approve the member’s reports. +8. Click **Save**. + +
diff --git a/docs/articles/expensify-classic/workspaces/Set-time-and-distance-rates.md b/docs/articles/expensify-classic/workspaces/Set-time-and-distance-rates.md new file mode 100644 index 000000000000..e81e05446379 --- /dev/null +++ b/docs/articles/expensify-classic/workspaces/Set-time-and-distance-rates.md @@ -0,0 +1,24 @@ +--- +title: Set time and distance rates +description: Set rates for hourly and mileage expenses +--- +
+ +You can set rates for your workspace’s hourly billable and mileage expenses. + +1. Hover over Settings, then click **Workspaces**. +2. Click the **Group** tab on the left. +3. Click the desired workspace name. +4. Click the **Expenses** tab on the left. +5. Scroll down to the time or distance section and set your rates. + - For distance: + - If desired, adjust your unit (miles or kilometers) and your default category. These options will apply to all of your distance rates. + - To add a new rate, click **Add a Mileage Rate**. + - To edit an existing rate, + - Click the toggle to enable or disable the rate. + - Click the name or rate field to edit them. + - For time, + - Click the Enable toggle to enable hourly rate expenses. + - Enter the default hourly rate. + +
diff --git a/docs/assets/images/expensify-help.svg b/docs/assets/images/expensify-help.svg index 0655b947a27f..74fc63ffae96 100644 --- a/docs/assets/images/expensify-help.svg +++ b/docs/assets/images/expensify-help.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 5e2ba1fcd614..37741d484d63 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.55 + 1.4.56 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.55.3 + 1.4.56.5 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 69472200e46d..e228808076d0 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.4.55 + 1.4.56 CFBundleSignature ???? CFBundleVersion - 1.4.55.3 + 1.4.56.5 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 008ca16909b0..11f83011d47a 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 1.4.55 + 1.4.56 CFBundleVersion - 1.4.55.3 + 1.4.56.5 NSExtension NSExtensionPointIdentifier diff --git a/metro.config.js b/metro.config.js index 2422d29aaacf..68ed72d52ba0 100644 --- a/metro.config.js +++ b/metro.config.js @@ -7,7 +7,7 @@ require('dotenv').config(); const defaultConfig = getDefaultConfig(__dirname); const isE2ETesting = process.env.E2E_TESTING === 'true'; -const e2eSourceExts = ['e2e.js', 'e2e.ts']; +const e2eSourceExts = ['e2e.js', 'e2e.ts', 'e2e.tsx']; /** * Metro configuration diff --git a/package-lock.json b/package-lock.json index 4bff5eaf6eb8..6e7f23674852 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.55-3", + "version": "1.4.56-5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.55-3", + "version": "1.4.56-5", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -14,7 +14,6 @@ "@expensify/react-native-live-markdown": "0.1.5", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", - "@formatjs/intl-getcanonicallocales": "^2.2.0", "@formatjs/intl-listformat": "^7.2.2", "@formatjs/intl-locale": "^3.3.0", "@formatjs/intl-numberformat": "^8.5.0", @@ -73,6 +72,7 @@ "react-content-loader": "^7.0.0", "react-dom": "18.1.0", "react-error-boundary": "^4.0.11", + "react-fast-pdf": "^1.0.6", "react-map-gl": "^7.1.3", "react-native": "0.73.2", "react-native-android-location-enabler": "^2.0.1", @@ -25183,7 +25183,6 @@ }, "node_modules/dequal": { "version": "2.0.3", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -38922,6 +38921,74 @@ "react": ">=16.13.1" } }, + "node_modules/react-fast-pdf": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/react-fast-pdf/-/react-fast-pdf-1.0.6.tgz", + "integrity": "sha512-CdAnBSZaLCGLSEuiqWLzzXhV9Wvdf1VRixaXCrb3NFrXyeltahF7PY+u7eU6ynrWZGmNI6g0cMLPv0DQhJEeew==", + "dependencies": { + "react-pdf": "^7.7.0", + "react-window": "^1.8.10" + }, + "engines": { + "node": "20.10.0", + "npm": "10.2.3" + }, + "peerDependencies": { + "lodash": "4.x", + "prop-types": "15.x", + "react": "18.x", + "react-dom": "18.x" + } + }, + "node_modules/react-fast-pdf/node_modules/pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, + "node_modules/react-fast-pdf/node_modules/react-pdf": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.7.1.tgz", + "integrity": "sha512-cbbf/PuRtGcPPw+HLhMI1f6NSka8OJgg+j/yPWTe95Owf0fK6gmVY7OXpTxMeh92O3T3K3EzfE0ML0eXPGwR5g==", + "dependencies": { + "clsx": "^2.0.0", + "dequal": "^2.0.3", + "make-cancellable-promise": "^1.3.1", + "make-event-props": "^1.6.0", + "merge-refs": "^1.2.1", + "pdfjs-dist": "3.11.174", + "prop-types": "^15.6.2", + "tiny-invariant": "^1.0.0", + "warning": "^4.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-pdf?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-fast-pdf/node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/react-freeze": { "version": "1.0.3", "license": "MIT", @@ -40398,8 +40465,9 @@ } }, "node_modules/react-window": { - "version": "1.8.9", - "license": "MIT", + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", + "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", "dependencies": { "@babel/runtime": "^7.0.0", "memoize-one": ">=3.1.1 <6" diff --git a/package.json b/package.json index 53eb229d7b85..83c3095585be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.55-3", + "version": "1.4.56-5", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", @@ -50,8 +50,8 @@ "analyze-packages": "ANALYZE_BUNDLE=true webpack --config config/webpack/webpack.common.js --env envFile=.env.production", "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map", "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map", - "symbolicate-release:ios": "scripts/release-profile.js --platform=ios", - "symbolicate-release:android": "scripts/release-profile.js --platform=android", + "symbolicate-release:ios": "scripts/release-profile.ts --platform=ios", + "symbolicate-release:android": "scripts/release-profile.ts --platform=android", "test:e2e": "ts-node tests/e2e/testRunner.ts --config ./config.local.ts", "test:e2e:dev": "ts-node tests/e2e/testRunner.ts --config ./config.dev.ts", "gh-actions-unused-styles": "./.github/scripts/findUnusedKeys.sh", @@ -65,7 +65,6 @@ "@expensify/react-native-live-markdown": "0.1.5", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", - "@formatjs/intl-getcanonicallocales": "^2.2.0", "@formatjs/intl-listformat": "^7.2.2", "@formatjs/intl-locale": "^3.3.0", "@formatjs/intl-numberformat": "^8.5.0", @@ -124,6 +123,7 @@ "react-content-loader": "^7.0.0", "react-dom": "18.1.0", "react-error-boundary": "^4.0.11", + "react-fast-pdf": "^1.0.6", "react-map-gl": "^7.1.3", "react-native": "0.73.2", "react-native-android-location-enabler": "^2.0.1", @@ -154,8 +154,8 @@ "react-native-plaid-link-sdk": "10.8.0", "react-native-qrcode-svg": "^6.2.0", "react-native-quick-sqlite": "^8.0.0-beta.2", - "react-native-release-profiler": "^0.1.6", "react-native-reanimated": "^3.7.2", + "react-native-release-profiler": "^0.1.6", "react-native-render-html": "6.3.1", "react-native-safe-area-context": "4.8.2", "react-native-screens": "3.29.0", diff --git a/scripts/build-desktop.sh b/scripts/build-desktop.sh index 025559dc4671..efbca35a498c 100755 --- a/scripts/build-desktop.sh +++ b/scripts/build-desktop.sh @@ -13,8 +13,18 @@ else ENV_FILE=".env" fi +if [[ -n "$GCP_GEOLOCATION_API_KEY" ]]; then + if grep -qE "^GCP_GEOLOCATION_API_KEY=" "$ENV_FILE"; then + # Replace the value for the existing key + sed -i "s|^GCP_GEOLOCATION_API_KEY=.*$|GCP_GEOLOCATION_API_KEY=$GCP_GEOLOCATION_API_KEY|g" "$ENV_FILE" + else + # Add the key-value pair to the config file + echo "GCP_GEOLOCATION_API_KEY=$GCP_GEOLOCATION_API_KEY" >> "$ENV_FILE" + fi +fi + SCRIPTS_DIR=$(dirname "${BASH_SOURCE[0]}") -source "$SCRIPTS_DIR/shellUtils.sh"; +source "$SCRIPTS_DIR/shellUtils.sh" title "Bundling Desktop js Bundle Using Webpack" info " • ELECTRON_ENV: $ELECTRON_ENV" diff --git a/scripts/release-profile.js b/scripts/release-profile.ts similarity index 83% rename from scripts/release-profile.js rename to scripts/release-profile.ts index 0f96232bcdca..8ec0979f9f9e 100755 --- a/scripts/release-profile.js +++ b/scripts/release-profile.ts @@ -1,13 +1,15 @@ -#!/usr/bin/env node +#!/usr/bin/env ts-node + /* eslint-disable no-console */ +import {execSync} from 'child_process'; +import fs from 'fs'; -const fs = require('fs'); -const {execSync} = require('child_process'); +type ArgsMap = Record; // Function to parse command-line arguments into a key-value object -function parseCommandLineArguments() { +function parseCommandLineArguments(): ArgsMap { const args = process.argv.slice(2); // Skip node and script paths - const argsMap = {}; + const argsMap: ArgsMap = {}; args.forEach((arg) => { const [key, value] = arg.split('='); if (key.startsWith('--')) { @@ -20,14 +22,13 @@ function parseCommandLineArguments() { // Function to find .cpuprofile files in the current directory function findCpuProfileFiles() { const files = fs.readdirSync(process.cwd()); - // eslint-disable-next-line rulesdir/prefer-underscore-method return files.filter((file) => file.endsWith('.cpuprofile')); } const argsMap = parseCommandLineArguments(); // Determine sourcemapPath based on the platform flag passed -let sourcemapPath; +let sourcemapPath: string | undefined; if (argsMap.platform === 'ios') { sourcemapPath = 'main.jsbundle.map'; } else if (argsMap.platform === 'android') { @@ -57,7 +58,10 @@ if (cpuProfiles.length === 0) { const output = execSync(command, {stdio: 'inherit'}); console.log(output.toString()); } catch (error) { - console.error(`Error executing command: ${error}`); + if (error instanceof Error) { + console.error(`Error executing command: ${error.toString()}`); + } + process.exit(1); } } diff --git a/src/App.tsx b/src/App.tsx index 236e20df33b3..a3a9f7a3f3b6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ import {LocaleContextProvider} from './components/LocaleContextProvider'; import OnyxProvider from './components/OnyxProvider'; import PopoverContextProvider from './components/PopoverProvider'; import SafeArea from './components/SafeArea'; +import ScrollOffsetContextProvider from './components/ScrollOffsetContextProvider'; import ThemeIllustrationsProvider from './components/ThemeIllustrationsProvider'; import ThemeProvider from './components/ThemeProvider'; import ThemeStylesProvider from './components/ThemeStylesProvider'; @@ -70,6 +71,7 @@ function App({url}: AppProps) { KeyboardStateProvider, PopoverContextProvider, CurrentReportIDContextProvider, + ScrollOffsetContextProvider, ReportAttachmentsProvider, PickerStateProvider, EnvironmentProvider, diff --git a/src/CONST.ts b/src/CONST.ts index af4864c22a85..d5ad5584126c 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -335,6 +335,7 @@ const CONST = { TRACK_EXPENSE: 'trackExpense', P2P_DISTANCE_REQUESTS: 'p2pDistanceRequests', WORKFLOWS_DELAYED_SUBMISSION: 'workflowsDelayedSubmission', + ACCOUNTING: 'accounting', }, BUTTON_STATES: { DEFAULT: 'default', @@ -1501,6 +1502,15 @@ const CONST = { DISABLE: 'disable', ENABLE: 'enable', }, + OWNERSHIP_ERRORS: { + NO_BILLING_CARD: 'noBillingCard', + AMOUNT_OWED: 'amountOwed', + HAS_FAILED_SETTLEMENTS: 'hasFailedSettlements', + OWNER_OWES_AMOUNT: 'ownerOwesAmount', + SUBSCRIPTION: 'subscription', + DUPLICATE_SUBSCRIPTION: 'duplicateSubscription', + FAILED_TO_CLEAR_BALANCE: 'failedToClearBalance', + }, TAX_RATES_BULK_ACTION_TYPES: { DELETE: 'delete', DISABLE: 'disable', @@ -1679,7 +1689,7 @@ const CONST = { POLICY_ID_FROM_PATH: /\/w\/([a-zA-Z0-9]+)(\/|$)/, - SHORT_MENTION: new RegExp(`@[\\w\\-\\+\\'#]+(?:\\.[\\w\\-\\'\\+]+)*`, 'gim'), + SHORT_MENTION: new RegExp(`@[\\w\\-\\+\\'#@]+(?:\\.[\\w\\-\\'\\+]+)*`, 'gim'), }, PRONOUNS: { @@ -1850,13 +1860,6 @@ const CONST = { MAX_INT_FOR_RANDOM_7_DIGIT_VALUE: 10000000, IOS_KEYBOARD_SPACE_OFFSET: -30, - PDF_PASSWORD_FORM: { - // Constants for password-related error responses received from react-pdf. - REACT_PDF_PASSWORD_RESPONSES: { - NEED_PASSWORD: 1, - INCORRECT_PASSWORD: 2, - }, - }, API_REQUEST_TYPE: { READ: 'read', WRITE: 'write', @@ -2980,7 +2983,7 @@ const CONST = { CURRENCY: 'XAF', FORMAT: 'symbol', SAMPLE_INPUT: '123456.789', - EXPECTED_OUTPUT: 'FCFA 123,457', + EXPECTED_OUTPUT: 'FCFA 123,457', }, PATHS_TO_TREAT_AS_EXTERNAL: ['NewExpensify.dmg', 'docs/index.html'], @@ -4133,6 +4136,24 @@ const CONST = { SESSION_STORAGE_KEYS: { INITIAL_URL: 'INITIAL_URL', }, + DEFAULT_TAX: { + defaultExternalID: 'id_TAX_EXEMPT', + defaultValue: '0%', + foreignTaxDefault: 'id_TAX_EXEMPT', + name: 'Tax', + taxes: { + id_TAX_EXEMPT: { + name: 'Tax exempt', + value: '0%', + }, + id_TAX_RATE_1: { + name: 'Tax Rate 1', + value: '5%', + }, + }, + }, + + MAX_TAX_RATE_DECIMAL_PLACES: 4, } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index d3fab1b9fcde..b38e191a2a98 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -290,6 +290,9 @@ const ONYXKEYS = { // Paths of PDF file that has been cached during one session CACHED_PDF_PATHS: 'cachedPDFPaths', + /** Holds the checks used while transferring the ownership of the workspace */ + POLICY_OWNERSHIP_CHANGE_CHECKS: 'policyOwnershipChangeChecks', + /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', @@ -620,6 +623,7 @@ type OnyxValuesMapping = { [ONYXKEYS.LOGS]: Record; [ONYXKEYS.SHOULD_STORE_LOGS]: boolean; [ONYXKEYS.CACHED_PDF_PATHS]: Record; + [ONYXKEYS.POLICY_OWNERSHIP_CHANGE_CHECKS]: Record; [ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE]: OnyxTypes.QuickAction; }; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index c216d5ac288c..23bb2ee845ad 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -179,7 +179,7 @@ const ROUTES = { REPORT: 'r', REPORT_WITH_ID: { route: 'r/:reportID?/:reportActionID?', - getRoute: (reportID: string) => `r/${reportID}` as const, + getRoute: (reportID: string, reportActionID?: string) => (reportActionID ? (`r/${reportID}/${reportActionID}` as const) : (`r/${reportID}` as const)), }, REPORT_AVATAR: { route: 'r/:reportID/avatar', @@ -612,6 +612,19 @@ const ROUTES = { route: 'settings/workspaces/:policyID/members/:accountID/role-selection', getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/members/${accountID}/role-selection`, backTo), }, + WORKSPACE_OWNER_CHANGE_SUCCESS: { + route: 'settings/workspaces/:policyID/change-owner/:accountID/success', + getRoute: (policyID: string, accountID: number) => `settings/workspaces/${policyID}/change-owner/${accountID}/success` as const, + }, + WORKSPACE_OWNER_CHANGE_ERROR: { + route: 'settings/workspaces/:policyID/change-owner/:accountID/failure', + getRoute: (policyID: string, accountID: number) => `settings/workspaces/${policyID}/change-owner/${accountID}/failure` as const, + }, + WORKSPACE_OWNER_CHANGE_CHECK: { + route: 'settings/workspaces/:policyID/change-owner/:accountID/:error', + getRoute: (policyID: string, accountID: number, error: ValueOf) => + `settings/workspaces/${policyID}/change-owner/${accountID}/${error}` as const, + }, WORKSPACE_TAX_CREATE: { route: 'settings/workspaces/:policyID/taxes/new', getRoute: (policyID: string) => `settings/workspaces/${policyID}/taxes/new` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 82fef0383918..ffb18391c980 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -242,6 +242,9 @@ const SCREENS = { MORE_FEATURES: 'Workspace_More_Features', MEMBER_DETAILS: 'Workspace_Member_Details', MEMBER_DETAILS_ROLE_SELECTION: 'Workspace_Member_Details_Role_Selection', + OWNER_CHANGE_CHECK: 'Workspace_Owner_Change_Check', + OWNER_CHANGE_SUCCESS: 'Workspace_Owner_Change_Success', + OWNER_CHANGE_ERROR: 'Workspace_Owner_Change_Error', DISTANCE_RATES: 'Distance_Rates', CREATE_DISTANCE_RATE: 'Create_Distance_Rate', DISTANCE_RATES_SETTINGS: 'Distance_Rates_Settings', diff --git a/src/components/AddPaymentMethodMenu.js b/src/components/AddPaymentMethodMenu.tsx similarity index 63% rename from src/components/AddPaymentMethodMenu.js rename to src/components/AddPaymentMethodMenu.tsx index 803b7f2cdabe..ac9657694500 100644 --- a/src/components/AddPaymentMethodMenu.js +++ b/src/components/AddPaymentMethodMenu.tsx @@ -1,78 +1,75 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; +import type {RefObject} from 'react'; import React from 'react'; +import type {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; import useLocalize from '@hooks/useLocalize'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import iouReportPropTypes from '@pages/iouReportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {AnchorPosition} from '@src/styles'; +import type {Report, Session} from '@src/types/onyx'; +import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; import * as Expensicons from './Icon/Expensicons'; +import type {PaymentMethod} from './KYCWall/types'; import PopoverMenu from './PopoverMenu'; -import refPropTypes from './refPropTypes'; -const propTypes = { +type AddPaymentMethodMenuOnyxProps = { + /** Session info for the currently logged-in user. */ + session: OnyxEntry; +}; + +type AddPaymentMethodMenuProps = AddPaymentMethodMenuOnyxProps & { /** Should the component be visible? */ - isVisible: PropTypes.bool.isRequired, + isVisible: boolean; /** Callback to execute when the component closes. */ - onClose: PropTypes.func.isRequired, + onClose: () => void; /** Callback to execute when the payment method is selected. */ - onItemSelected: PropTypes.func.isRequired, + onItemSelected: (paymentMethod: PaymentMethod) => void; /** The IOU/Expense report we are paying */ - iouReport: iouReportPropTypes, + iouReport?: OnyxEntry | EmptyObject; /** Anchor position for the AddPaymentMenu. */ - anchorPosition: PropTypes.shape({ - horizontal: PropTypes.number, - vertical: PropTypes.number, - }), + anchorPosition: AnchorPosition; /** Where the popover should be positioned relative to the anchor points. */ - anchorAlignment: PropTypes.shape({ - horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)), - vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)), - }), + anchorAlignment?: AnchorAlignment; /** Popover anchor ref */ - anchorRef: refPropTypes, - - /** Session info for the currently logged in user. */ - session: PropTypes.shape({ - /** Currently logged in user accountID */ - accountID: PropTypes.number, - }), + anchorRef: RefObject; /** Whether the personal bank account option should be shown */ - shouldShowPersonalBankAccountOption: PropTypes.bool, + shouldShowPersonalBankAccountOption?: boolean; }; -const defaultProps = { - iouReport: {}, - anchorPosition: {}, - anchorAlignment: { +function AddPaymentMethodMenu({ + isVisible, + onClose, + anchorPosition, + anchorAlignment = { horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM, }, - anchorRef: () => {}, - session: {}, - shouldShowPersonalBankAccountOption: false, -}; - -function AddPaymentMethodMenu({isVisible, onClose, anchorPosition, anchorAlignment, anchorRef, iouReport, onItemSelected, session, shouldShowPersonalBankAccountOption}) { + anchorRef, + iouReport, + onItemSelected, + session, + shouldShowPersonalBankAccountOption = false, +}: AddPaymentMethodMenuProps) { const {translate} = useLocalize(); // Users can choose to pay with business bank account in case of Expense reports or in case of P2P IOU report // which then starts a bottom up flow and creates a Collect workspace where the payer is an admin and payee is an employee. + const isIOUReport = ReportUtils.isIOUReport(iouReport ?? {}); const canUseBusinessBankAccount = - ReportUtils.isExpenseReport(iouReport) || - (ReportUtils.isIOUReport(iouReport) && !ReportActionsUtils.hasRequestFromCurrentAccount(lodashGet(iouReport, 'reportID', 0), lodashGet(session, 'accountID', 0))); + ReportUtils.isExpenseReport(iouReport ?? {}) || (isIOUReport && !ReportActionsUtils.hasRequestFromCurrentAccount(iouReport?.reportID ?? '', session?.accountID ?? 0)); - const canUsePersonalBankAccount = shouldShowPersonalBankAccountOption || ReportUtils.isIOUReport(iouReport); + const canUsePersonalBankAccount = shouldShowPersonalBankAccountOption || isIOUReport; return ( ({ session: { key: ONYXKEYS.SESSION, }, diff --git a/src/components/AddressSearch/index.tsx b/src/components/AddressSearch/index.tsx index 9901ff9243f9..d0aa2e206eb2 100644 --- a/src/components/AddressSearch/index.tsx +++ b/src/components/AddressSearch/index.tsx @@ -455,3 +455,5 @@ function AddressSearch( AddressSearch.displayName = 'AddressSearchWithRef'; export default forwardRef(AddressSearch); + +export type {AddressSearchProps}; diff --git a/src/components/AddressSearch/types.ts b/src/components/AddressSearch/types.ts index 27e068cd1777..efbcc6374341 100644 --- a/src/components/AddressSearch/types.ts +++ b/src/components/AddressSearch/types.ts @@ -96,4 +96,4 @@ type AddressSearchProps = { type IsCurrentTargetInsideContainerType = (event: FocusEvent | NativeSyntheticEvent, containerRef: RefObject) => boolean; -export type {CurrentLocationButtonProps, AddressSearchProps, RenamedInputKeysProps, IsCurrentTargetInsideContainerType}; +export type {CurrentLocationButtonProps, AddressSearchProps, RenamedInputKeysProps, IsCurrentTargetInsideContainerType, StreetValue}; diff --git a/src/components/AmountForm.tsx b/src/components/AmountForm.tsx index 48035dd884bd..e947c74f7c60 100644 --- a/src/components/AmountForm.tsx +++ b/src/components/AmountForm.tsx @@ -37,6 +37,9 @@ type AmountFormProps = { /** Whether the currency symbol is pressable */ isCurrencyPressable?: boolean; + + /** Custom max amount length. It defaults to CONST.IOU.AMOUNT_MAX_LENGTH */ + amountMaxLength?: number; } & Pick & Pick; @@ -53,7 +56,7 @@ const NUM_PAD_CONTAINER_VIEW_ID = 'numPadContainerView'; const NUM_PAD_VIEW_ID = 'numPadView'; function AmountForm( - {value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, errorText, onInputChange, onCurrencyButtonPress, isCurrencyPressable = true, ...rest}: AmountFormProps, + {value: amount, currency = CONST.CURRENCY.USD, extraDecimals = 0, amountMaxLength, errorText, onInputChange, onCurrencyButtonPress, isCurrencyPressable = true, ...rest}: AmountFormProps, forwardedRef: ForwardedRef, ) { const styles = useThemeStyles(); @@ -101,7 +104,7 @@ function AmountForm( const newAmountWithoutSpaces = MoneyRequestUtils.stripSpacesFromAmount(newAmount); // Use a shallow copy of selection to trigger setSelection // More info: https://github.com/Expensify/App/issues/16385 - if (!MoneyRequestUtils.validateAmount(newAmountWithoutSpaces, decimals)) { + if (!MoneyRequestUtils.validateAmount(newAmountWithoutSpaces, decimals, amountMaxLength)) { setSelection((prevSelection) => ({...prevSelection})); return; } @@ -111,13 +114,13 @@ function AmountForm( setSelection((prevSelection) => getNewSelection(prevSelection, isForwardDelete ? strippedAmount.length : currentAmount.length, strippedAmount.length)); onInputChange?.(strippedAmount); }, - [currentAmount, decimals, onInputChange], + [amountMaxLength, currentAmount, decimals, onInputChange], ); // Modifies the amount to match the decimals for changed currency. useEffect(() => { // If the changed currency supports decimals, we can return - if (MoneyRequestUtils.validateAmount(currentAmount, decimals)) { + if (MoneyRequestUtils.validateAmount(currentAmount, decimals, amountMaxLength)) { return; } diff --git a/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx b/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx index d389ac4b92f0..da8e3694a7d2 100644 --- a/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx +++ b/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx @@ -59,7 +59,6 @@ function BaseAnchorForAttachmentsOnly({style, source = '', displayName = '', dow role={CONST.ROLE.BUTTON} > ; }; -type Attachment = { - source: AvatarSource; - isAuthTokenRequired: boolean; - file: FileObject; - isReceipt: boolean; - hasBeenFlagged?: boolean; - reportActionID?: string; -}; - type ImagePickerResponse = { - height: number; + height?: number; name: string; - size: number; + size?: number | null; type: string; uri: string; - width: number; + width?: number; }; -type FileObject = File | ImagePickerResponse; +type FileObject = Partial; type ChildrenProps = { displayFileInModal: (data: FileObject) => void; @@ -181,7 +173,7 @@ function AttachmentModal({ const [isAuthTokenRequiredState, setIsAuthTokenRequiredState] = useState(isAuthTokenRequired); const [attachmentInvalidReasonTitle, setAttachmentInvalidReasonTitle] = useState(null); const [attachmentInvalidReason, setAttachmentInvalidReason] = useState(null); - const [sourceState, setSourceState] = useState(() => source); + const [sourceState, setSourceState] = useState(() => source); const [modalType, setModalType] = useState(CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE); const [isConfirmButtonDisabled, setIsConfirmButtonDisabled] = useState(false); const [confirmButtonFadeAnimation] = useState(() => new Animated.Value(1)); @@ -190,7 +182,7 @@ function AttachmentModal({ const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); const isOverlayModalVisible = (isReceiptAttachment && isDeleteReceiptConfirmModalVisible) || (!isReceiptAttachment && isAttachmentInvalid); - const [file, setFile] = useState | undefined>( + const [file, setFile] = useState( originalFileName ? { name: originalFileName, @@ -211,7 +203,7 @@ function AttachmentModal({ (attachment: Attachment) => { setSourceState(attachment.source); setFile(attachment.file); - setIsAuthTokenRequiredState(attachment.isAuthTokenRequired); + setIsAuthTokenRequiredState(attachment.isAuthTokenRequired ?? false); onCarouselAttachmentChange(attachment); }, [onCarouselAttachmentChange], @@ -222,7 +214,7 @@ function AttachmentModal({ */ const getModalType = useCallback( (sourceURL: string, fileObject: FileObject) => - sourceURL && (Str.isPDF(sourceURL) || (fileObject && Str.isPDF(fileObject.name || translate('attachmentView.unknownFilename')))) + sourceURL && (Str.isPDF(sourceURL) || (fileObject && Str.isPDF(fileObject.name ?? translate('attachmentView.unknownFilename')))) ? CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE : CONST.MODAL.MODAL_TYPE.CENTERED, [translate], @@ -292,14 +284,14 @@ function AttachmentModal({ }, [transaction, report]); const isValidFile = useCallback((fileObject: FileObject) => { - if (fileObject.size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { + if (fileObject.size && fileObject.size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { setIsAttachmentInvalid(true); setAttachmentInvalidReasonTitle('attachmentPicker.attachmentTooLarge'); setAttachmentInvalidReason('attachmentPicker.sizeExceeded'); return false; } - if (fileObject.size < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { + if (fileObject.size && fileObject.size < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { setIsAttachmentInvalid(true); setAttachmentInvalidReasonTitle('attachmentPicker.attachmentTooSmall'); setAttachmentInvalidReason('attachmentPicker.sizeNotMet'); @@ -352,7 +344,7 @@ function AttachmentModal({ setSourceState(inputSource); setFile(updatedFile); setModalType(inputModalType); - } else { + } else if (fileObject.uri) { const inputModalType = getModalType(fileObject.uri, fileObject); setIsModalOpen(true); setSourceState(fileObject.uri); @@ -536,7 +528,6 @@ function AttachmentModal({ onNavigate={onNavigate} onClose={closeModal} source={source} - onToggleKeyboard={updateConfirmButtonVisibility} setDownloadButtonVisibility={setDownloadButtonVisibility} /> ) : ( @@ -546,10 +537,9 @@ function AttachmentModal({ !shouldShowNotFoundPage && ( ({ }, })(memo(AttachmentModal)); -export type {Attachment, FileObject}; +export type {Attachment, FileObject, ImagePickerResponse}; diff --git a/src/components/AttachmentPicker/attachmentPickerPropTypes.js b/src/components/AttachmentPicker/attachmentPickerPropTypes.js deleted file mode 100644 index a3a346f5ea27..000000000000 --- a/src/components/AttachmentPicker/attachmentPickerPropTypes.js +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types'; -import CONST from '@src/CONST'; - -const propTypes = { - /** - * A renderProp with the following interface - * - * @example - * - * {({openPicker}) => ( - *