From 5e46a7f47f2bcc5eaaa281e6ad4e134f2abcb9a7 Mon Sep 17 00:00:00 2001 From: gets0ul Date: Wed, 25 May 2022 19:33:55 +0700 Subject: [PATCH 01/28] Refresh copilot Gitlab access token automatically when needed. --- config/default.js | 7 ++++- configuration.md | 3 ++ index.js | 4 ++- services/GitlabService.js | 65 +++++++++++++++++++++++++++++++++------ services/UserService.js | 2 ++ 5 files changed, 70 insertions(+), 11 deletions(-) diff --git a/config/default.js b/config/default.js index 632c5ca..e17d3f4 100644 --- a/config/default.js +++ b/config/default.js @@ -74,5 +74,10 @@ module.exports = { ROLE_ID_SUBMITTER: process.env.ROLE_ID_SUBMITTER || '732339e7-8e30-49d7-9198-cccf9451e221', TYPE_ID_TASK: process.env.TYPE_ID_TASK || 'ecd58c69-238f-43a4-a4bb-d172719b9f31', DEFAULT_TIMELINE_TEMPLATE_ID: process.env.DEFAULT_TIMELINE_TEMPLATE_ID || '53a307ce-b4b3-4d6f-b9a1-3741a58f77e6', - DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825' + DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825', + GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION: 3600 * 2, + GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION: 300, + GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID, + GITLAB_CLIENT_SECRET: process.env.GITLAB_CLIENT_SECRET, + GITLAB_OWNER_USER_CALLBACK_URL: process.env.GITLAB_OWNER_USER_CALLBACK_URL }; diff --git a/configuration.md b/configuration.md index 5ca0e4f..a8f5ddb 100644 --- a/configuration.md +++ b/configuration.md @@ -16,6 +16,9 @@ The following config parameters are supported, they are defined in `config/defau | NEW_CHALLENGE_DURATION_IN_DAYS | the duration of new challenge | 5 | |TC_URL| the base URL of topcoder to get the challenge URL| defaults to `https://www.topcoder-dev.com`| |GITLAB_API_BASE_URL| the URL for gitlab host| defaults to `https://gitlab.com`| +| GITLAB_CLIENT_ID | the GitLab client id | No default - needs to be set up with same value found in topcoder-x-ui | +| GITLAB_CLIENT_SECRET | the GitLab client secret | No default - needs to be set up with same value found in topcoder-x-ui | +| GITLAB_OWNER_USER_CALLBACK_URL | the GitLab callback redirect uri for refreshing copilot token | No default - needs to be set up with same owner user callback value in topcoder-x-ui | |PAID_ISSUE_LABEL|the label name for paid, should be one of the label configured in topcoder x ui|'tcx_Paid'| |FIX_ACCEPTED_ISSUE_LABEL|the label name for fix accepted, should be one of the label configured in topcoder x ui|'tcx_FixAccepted'| |ASSIGNED_ISSUE_LABEL| the label name for assigned, should be one of the label configured in topcoder x ui| 'tcx_Assigned'| diff --git a/index.js b/index.js index ee57023..ef15b99 100644 --- a/index.js +++ b/index.js @@ -22,7 +22,9 @@ process.on('unhandledRejection', (err) => { }); // dump the configuration to logger -const ignoreConfigLog = ['cert', 'key', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET']; +const ignoreConfigLog = ['cert', 'key', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', + 'GITLAB_CLIENT_ID', 'GITLAB_CLIENT_SECRET']; + /** * Print configs to logger * @param {Object} params the config params diff --git a/services/GitlabService.js b/services/GitlabService.js index 542e9bb..559b31c 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -16,9 +16,18 @@ const GitlabAPI = require('node-gitlab-api'); const logger = require('../utils/logger'); const errors = require('../utils/errors'); const helper = require('../utils/helper'); +const dbHelper = require('../utils/db-helper'); +const superagent = require('superagent'); +const superagentPromise = require('superagent-promise'); + +const request = superagentPromise(superagent, Promise); +// milliseconds per second +const MS_PER_SECOND = 1000; const copilotUserSchema = Joi.object().keys({ accessToken: Joi.string().required(), + accessTokenExpiration: Joi.date().required(), + refreshToken: Joi.string().required(), userProviderId: Joi.number().required(), topcoderUsername: Joi.string() }).required(); @@ -80,7 +89,8 @@ function _getIssueUrl(repoPath, issueId) { async function createComment(copilot, project, issueId, body) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, body}, createComment.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); try { body = helper.prepareAutomatedComment(body, copilot); await gitlab.projects.issues.notes.create(projectId, issueId, {body}); @@ -107,7 +117,8 @@ createComment.schema = { async function updateIssue(copilot, project, issueId, title) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, title}, updateIssue.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); try { await gitlab.projects.issues.edit(projectId, issueId, {title}); } catch (err) { @@ -133,7 +144,8 @@ updateIssue.schema = { async function assignUser(copilot, project, issueId, userId) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, userId}, assignUser.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); try { const issue = await gitlab.projects.issues.show(projectId, issueId); const oldAssignees = _.without(issue.assignee_ids, userId); @@ -164,7 +176,8 @@ assignUser.schema = { async function removeAssign(copilot, project, issueId, userId) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, userId}, removeAssign.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); await _removeAssignees(gitlab, projectId, issueId, [userId]); logger.debug(`Gitlab user ${userId} is unassigned from issue number ${issueId}`); } @@ -179,7 +192,8 @@ removeAssign.schema = assignUser.schema; */ async function getUsernameById(copilot, userId) { Joi.attempt({copilot, userId}, getUsernameById.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); const user = await gitlab.users.show(userId); return user ? user.username : null; } @@ -197,7 +211,8 @@ getUsernameById.schema = { */ async function getUserIdByLogin(copilot, login) { Joi.attempt({copilot, login}, getUserIdByLogin.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); const user = await gitlab.users.all({username: login}); return user.length ? user[0].id : null; } @@ -220,7 +235,8 @@ getUserIdByLogin.schema = { async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params const projectId = project.id; Joi.attempt({copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments}, markIssueAsPaid.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL) .push(config.FIX_ACCEPTED_ISSUE_LABEL, config.PAID_ISSUE_LABEL).value(); try { @@ -263,7 +279,8 @@ markIssueAsPaid.schema = { async function changeState(copilot, project, issueId, state) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, state}, changeState.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); try { await gitlab.projects.issues.edit(projectId, issueId, {state_event: state}); } catch (err) { @@ -289,7 +306,8 @@ changeState.schema = { async function addLabels(copilot, project, issueId, labels) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, labels}, addLabels.schema); - const gitlab = await _authenticate(copilot.accessToken); + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); try { await gitlab.projects.issues.edit(projectId, issueId, {labels: _.join(labels, ',')}); } catch (err) { @@ -305,6 +323,35 @@ addLabels.schema = { labels: Joi.array().items(Joi.string()).required() }; +/** + * Refresh the copilot access token if token is needed + * @param {Object} copilot the copilot + * @returns {Promise} the promise result of copilot with refreshed token + */ +async function _refreshGitlabUserAccessToken(copilot) { + if (copilot.accessTokenExpiration && new Date().getTime() > copilot.accessTokenExpiration.getTime() - + (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { + const refreshTokenResult = await request + .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) + .query({ + client_id: config.GITLAB_CLIENT_ID, + client_secret: config.GITLAB_CLIENT_SECRET, + refresh_token: copilot.refreshToken, + grant_type: 'refresh_token', + redirect_uri: config.GITLAB_OWNER_USER_CALLBACK_URL, + }) + .end(); + // save user token data + const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; + return await dbHelper.update(User, copilot.id, { + accessToken: refreshTokenResult.body.access_token, + accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), + refreshToken: refreshTokenResult.body.refresh_token, + }); + } + return copilot; +} + module.exports = { createComment, diff --git a/services/UserService.js b/services/UserService.js index 3b1b342..71379e7 100755 --- a/services/UserService.js +++ b/services/UserService.js @@ -97,6 +97,8 @@ async function getRepositoryCopilotOrOwner(provider, repoFullName) { return { accessToken: user.accessToken, + accessTokenExpiration: user.accessTokenExpiration, + refreshToken: user.refreshToken, userProviderId: user.userProviderId, topcoderUsername: userMapping.topcoderUsername }; From af42897d3076cc704f494924b1de9dcf6ed63706 Mon Sep 17 00:00:00 2001 From: 52code Date: Thu, 2 Jun 2022 12:15:45 +0800 Subject: [PATCH 02/28] https://github.com/topcoder-platform/topcoder-x-ui/issues/453 --- models/Project.js | 5 +++ services/ChallengeService.js | 65 +++++++++++++++++++++++++++++++ services/CopilotPaymentService.js | 1 + services/IssueService.js | 1 + utils/db-helper.js | 19 +++++++++ utils/kafka-consumer.js | 7 ++++ 6 files changed, 98 insertions(+) create mode 100644 services/ChallengeService.js diff --git a/models/Project.js b/models/Project.js index 08a7837..c27edc1 100755 --- a/models/Project.js +++ b/models/Project.js @@ -23,6 +23,11 @@ const schema = new Schema({ type: Number, required: true }, + tags: { + type: Array, + required: true, + default: [] + }, rocketChatWebhook: {type: String, required: false}, rocketChatChannelName: {type: String, required: false}, archived: {type: String, required: true}, diff --git a/services/ChallengeService.js b/services/ChallengeService.js new file mode 100644 index 0000000..f11f47f --- /dev/null +++ b/services/ChallengeService.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 TopCoder, Inc. All rights reserved. + */ +'use strict'; + +/** + * This service processes incoming pure challenge events. + * + * @author TCSCODER + * @version 1.0 + */ +const _ = require('lodash'); +const Joi = require('joi'); +const logger = require('../utils/logger'); +const topcoderApiHelper = require('../utils/topcoder-api-helper'); +const dbHelper = require('../utils/db-helper'); + +/** + * Update challenge tags + * @param {Object} event the event + */ +async handleChallengeTagsUpdate(event) { + const tags = event.data.tags; + try { + _.each(event.data.challengeUUIDsList, challengeUUIDs => { + if (_.isString(challengeUUIDs)) { // repoUrl + challengeUUIDs = await dbHelper.queryChallengeUUIDsByRepoUrl(challengeUUIDs); + } + _.each(challengeUUIDs, challengeUUID => await topcoderApiHelper.updateChallenge(challengeUUID, {tags})); + }); + } catch (err) { + logger.error(`handleChallengeTagsUpdate failed. Internal Error: ${err}`); + throw new Error(`handleChallengeTagsUpdate failed. Internal Error: ${err}`); + } +} + +/** + * Process pure challenge event. + * @param {Object} event the event + */ +async function process(event) { + Joi.attempt(event, process.schema); + + if (event.event === 'challengeTags.update') { + await handleChallengeTagsUpdate(event); + } +} + +process.schema = Joi.object().keys({ + event: Joi.string().valid('challengeUUIDTags.update').required(), + data: Joi.object().keys({ + challengeUUIDsList: Joi.array().items( + Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string())) + ).required(), + tags: Joi.array().items(Joi.string().required()).min(1).required(), + }).required(), + retryCount: Joi.number().integer().default(0).optional(), +}); + + +module.exports = { + process +}; + +logger.buildService(module.exports); diff --git a/services/CopilotPaymentService.js b/services/CopilotPaymentService.js index edfe5a4..6e54afe 100644 --- a/services/CopilotPaymentService.js +++ b/services/CopilotPaymentService.js @@ -194,6 +194,7 @@ async function handlePaymentAdd(event, payment) { const newChallenge = { name: challengeTitle, projectId: project.tcDirectId, + tags: project.tags, detailedRequirements: challengeRequirements, prizes: [payment.amount], reviewType: 'INTERNAL' diff --git a/services/IssueService.js b/services/IssueService.js index e1d1cb7..0c309f3 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -636,6 +636,7 @@ async function handleIssueCreate(event, issue, forceAssign = false) { issue.challengeUUID = await topcoderApiHelper.createChallenge({ name: issue.title, projectId, + tags: project.tags, detailedRequirements: issue.body, prizes: issue.prizes }); diff --git a/utils/db-helper.js b/utils/db-helper.js index 38425b5..8775177 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -342,6 +342,24 @@ async function queryOneActiveRepository(model, url) { }); } +/** + * Get Issue's challengeUUID by repoUrl + * @param {String} repoUrl The repo url + * @returns {Promise} + */ +async function queryChallengeUUIDsByRepoUrl(repoUrl) { + return await new Promise((resolve, reject) => { + models.Issue.scan('repoUrl').eq(repoUrl) + .attributes(['challengeUUID']) + .exec((err, results) => { + if (err) { + return reject(err); + } + return resolve(results.map({challengeUUID} => challengeUUID)); + }); + }); +} + module.exports = { getById, scan, @@ -357,6 +375,7 @@ module.exports = { queryOneUserMappingByGithubUsername, queryOneUserMappingByGitlabUsername, queryOneUserMappingByTCUsername, + queryChallengeUUIDsByRepoUrl, removeCopilotPayment, removeIssue }; diff --git a/utils/kafka-consumer.js b/utils/kafka-consumer.js index 65fc9c4..d9eda8d 100644 --- a/utils/kafka-consumer.js +++ b/utils/kafka-consumer.js @@ -12,6 +12,7 @@ const _ = require('lodash'); const healthcheck = require('topcoder-healthcheck-dropin'); const IssueService = require('../services/IssueService'); const CopilotPaymentService = require('../services/CopilotPaymentService'); +const ChallengeService = require('../services/ChallengeService'); const logger = require('./logger'); const kafka = require('./kafka'); @@ -47,6 +48,12 @@ function messageHandler(messageSet) { .process(event) .catch(logger.error); } + if (event && _.includes(['challengeUUIDTags.update'] + , event.event)) { + ChallengeService + .process(event) + .catch(logger.error); + } }); } From c15cd1f8fdafc60ef17934b7fd1aeb5c5abbc450 Mon Sep 17 00:00:00 2001 From: 52code Date: Thu, 2 Jun 2022 15:33:36 +0800 Subject: [PATCH 03/28] fix lint of PR#93 for topcoder-x-ui/Issue#453 --- services/ChallengeService.js | 20 +++++++++++--------- services/GitlabService.js | 7 ++++--- utils/db-helper.js | 9 ++++++--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/services/ChallengeService.js b/services/ChallengeService.js index f11f47f..7ecaa9d 100644 --- a/services/ChallengeService.js +++ b/services/ChallengeService.js @@ -19,19 +19,21 @@ const dbHelper = require('../utils/db-helper'); * Update challenge tags * @param {Object} event the event */ -async handleChallengeTagsUpdate(event) { +async function handleChallengeTagsUpdate(event) { const tags = event.data.tags; - try { - _.each(event.data.challengeUUIDsList, challengeUUIDs => { + await Promise.all( + event.data.challengeUUIDsList.map(async (challengeUUIDs) => { if (_.isString(challengeUUIDs)) { // repoUrl challengeUUIDs = await dbHelper.queryChallengeUUIDsByRepoUrl(challengeUUIDs); } - _.each(challengeUUIDs, challengeUUID => await topcoderApiHelper.updateChallenge(challengeUUID, {tags})); - }); - } catch (err) { + return challengeUUIDs.map(async (challengeUUID) => await topcoderApiHelper.updateChallenge(challengeUUID, {tags})); + }).reduce((a, b) => _.concat(a, b), []) + ).then((resps) => { + logger.debug(`handleChallengeTagsUpdate updated ${_.size(resps)} challenges successfully.`); + }).catch((err) => { logger.error(`handleChallengeTagsUpdate failed. Internal Error: ${err}`); throw new Error(`handleChallengeTagsUpdate failed. Internal Error: ${err}`); - } + }); } /** @@ -52,9 +54,9 @@ process.schema = Joi.object().keys({ challengeUUIDsList: Joi.array().items( Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string())) ).required(), - tags: Joi.array().items(Joi.string().required()).min(1).required(), + tags: Joi.array().items(Joi.string().required()).min(1).required() }).required(), - retryCount: Joi.number().integer().default(0).optional(), + retryCount: Joi.number().integer().default(0).optional() }); diff --git a/services/GitlabService.js b/services/GitlabService.js index 559b31c..9e100f3 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -15,6 +15,7 @@ const Joi = require('joi'); const GitlabAPI = require('node-gitlab-api'); const logger = require('../utils/logger'); const errors = require('../utils/errors'); +const models = require('../models'); const helper = require('../utils/helper'); const dbHelper = require('../utils/db-helper'); const superagent = require('superagent'); @@ -338,15 +339,15 @@ async function _refreshGitlabUserAccessToken(copilot) { client_secret: config.GITLAB_CLIENT_SECRET, refresh_token: copilot.refreshToken, grant_type: 'refresh_token', - redirect_uri: config.GITLAB_OWNER_USER_CALLBACK_URL, + redirect_uri: config.GITLAB_OWNER_USER_CALLBACK_URL }) .end(); // save user token data const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; - return await dbHelper.update(User, copilot.id, { + return await dbHelper.update(models.User, copilot.id, { accessToken: refreshTokenResult.body.access_token, accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), - refreshToken: refreshTokenResult.body.refresh_token, + refreshToken: refreshTokenResult.body.refresh_token }); } return copilot; diff --git a/utils/db-helper.js b/utils/db-helper.js index 8775177..29cc2e4 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -83,8 +83,10 @@ async function queryOneIssue(model, repositoryId, number, provider) { async function queryOneActiveProject(model, repoUrl) { return await new Promise((resolve, reject) => { queryOneActiveRepository(models.Repository, repoUrl).then((repo) => { - if (!repo) resolve(null); - else model.queryOne('id').eq(repo.projectId).consistent() + if (!repo) { + resolve(null); + } else { + model.queryOne('id').eq(repo.projectId).consistent() .exec((err, result) => { if (err) { logger.debug(`queryOneActiveProject. Error. ${err}`); @@ -92,6 +94,7 @@ async function queryOneActiveProject(model, repoUrl) { } return resolve(result); }); + } }); }); } @@ -355,7 +358,7 @@ async function queryChallengeUUIDsByRepoUrl(repoUrl) { if (err) { return reject(err); } - return resolve(results.map({challengeUUID} => challengeUUID)); + return resolve(results.map(({challengeUUID}) => challengeUUID)); }); }); } From 6997d3c781fb08ff5528356e98bc66e05f493718 Mon Sep 17 00:00:00 2001 From: 52code Date: Thu, 2 Jun 2022 22:50:58 +0800 Subject: [PATCH 04/28] https://github.com/topcoder-platform/topcoder-x-ui/issues/453 --- models/Project.js | 4 ++-- services/ChallengeService.js | 4 ++-- services/CopilotPaymentService.js | 2 +- services/IssueService.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/models/Project.js b/models/Project.js index c27edc1..df53b8d 100755 --- a/models/Project.js +++ b/models/Project.js @@ -24,9 +24,9 @@ const schema = new Schema({ required: true }, tags: { - type: Array, + type: String, required: true, - default: [] + default: '' }, rocketChatWebhook: {type: String, required: false}, rocketChatChannelName: {type: String, required: false}, diff --git a/services/ChallengeService.js b/services/ChallengeService.js index 7ecaa9d..6bcf787 100644 --- a/services/ChallengeService.js +++ b/services/ChallengeService.js @@ -20,7 +20,7 @@ const dbHelper = require('../utils/db-helper'); * @param {Object} event the event */ async function handleChallengeTagsUpdate(event) { - const tags = event.data.tags; + const tags = event.data.tags.split(','); await Promise.all( event.data.challengeUUIDsList.map(async (challengeUUIDs) => { if (_.isString(challengeUUIDs)) { // repoUrl @@ -54,7 +54,7 @@ process.schema = Joi.object().keys({ challengeUUIDsList: Joi.array().items( Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string())) ).required(), - tags: Joi.array().items(Joi.string().required()).min(1).required() + tags: Joi.string().required() }).required(), retryCount: Joi.number().integer().default(0).optional() }); diff --git a/services/CopilotPaymentService.js b/services/CopilotPaymentService.js index 6e54afe..7189510 100644 --- a/services/CopilotPaymentService.js +++ b/services/CopilotPaymentService.js @@ -194,7 +194,7 @@ async function handlePaymentAdd(event, payment) { const newChallenge = { name: challengeTitle, projectId: project.tcDirectId, - tags: project.tags, + tags: project.tags.split(','), detailedRequirements: challengeRequirements, prizes: [payment.amount], reviewType: 'INTERNAL' diff --git a/services/IssueService.js b/services/IssueService.js index 0c309f3..7413f11 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -636,7 +636,7 @@ async function handleIssueCreate(event, issue, forceAssign = false) { issue.challengeUUID = await topcoderApiHelper.createChallenge({ name: issue.title, projectId, - tags: project.tags, + tags: project.tags.split(','), detailedRequirements: issue.body, prizes: issue.prizes }); From 3736d024190be06d5a2c231b95d3ac7b3656b88d Mon Sep 17 00:00:00 2001 From: 52code Date: Fri, 3 Jun 2022 08:22:10 +0800 Subject: [PATCH 05/28] fix-empty-tags --- services/CopilotPaymentService.js | 2 +- services/IssueService.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/CopilotPaymentService.js b/services/CopilotPaymentService.js index 7189510..f828244 100644 --- a/services/CopilotPaymentService.js +++ b/services/CopilotPaymentService.js @@ -194,7 +194,7 @@ async function handlePaymentAdd(event, payment) { const newChallenge = { name: challengeTitle, projectId: project.tcDirectId, - tags: project.tags.split(','), + tags: !!project.tags ? project.tags.split(',') : [], detailedRequirements: challengeRequirements, prizes: [payment.amount], reviewType: 'INTERNAL' diff --git a/services/IssueService.js b/services/IssueService.js index 7413f11..0d24826 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -636,7 +636,7 @@ async function handleIssueCreate(event, issue, forceAssign = false) { issue.challengeUUID = await topcoderApiHelper.createChallenge({ name: issue.title, projectId, - tags: project.tags.split(','), + tags: !!project.tags ? project.tags.split(',') : [], detailedRequirements: issue.body, prizes: issue.prizes }); From 0d14af4c30db0e0f2ec199b492f310845c1f7bd1 Mon Sep 17 00:00:00 2001 From: 52code Date: Fri, 3 Jun 2022 09:55:10 +0800 Subject: [PATCH 06/28] add tags param --- utils/topcoder-api-helper.js | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index 94d18b1..ade67d0 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -75,6 +75,7 @@ async function createChallenge(challenge) { }], timelineTemplateId: config.DEFAULT_TIMELINE_TEMPLATE_ID, projectId: challenge.projectId, + tags: challenge.tags, trackId: config.DEFAULT_TRACK_ID, legacy: { pureV5Task: true From f254181f0bb1a7b31b00f6100d1fab3da64c0662 Mon Sep 17 00:00:00 2001 From: 52code Date: Fri, 3 Jun 2022 10:15:48 +0800 Subject: [PATCH 07/28] fix name of challenge event --- services/ChallengeService.js | 2 +- utils/kafka-consumer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/ChallengeService.js b/services/ChallengeService.js index 6bcf787..ae4dd22 100644 --- a/services/ChallengeService.js +++ b/services/ChallengeService.js @@ -49,7 +49,7 @@ async function process(event) { } process.schema = Joi.object().keys({ - event: Joi.string().valid('challengeUUIDTags.update').required(), + event: Joi.string().valid('challengeTags.update').required(), data: Joi.object().keys({ challengeUUIDsList: Joi.array().items( Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string())) diff --git a/utils/kafka-consumer.js b/utils/kafka-consumer.js index d9eda8d..c0e6fc5 100644 --- a/utils/kafka-consumer.js +++ b/utils/kafka-consumer.js @@ -48,7 +48,7 @@ function messageHandler(messageSet) { .process(event) .catch(logger.error); } - if (event && _.includes(['challengeUUIDTags.update'] + if (event && _.includes(['challengeTags.update'] , event.event)) { ChallengeService .process(event) From a902dd7e660de5bdfbdcc21d27ff797790804fe7 Mon Sep 17 00:00:00 2001 From: 52code Date: Tue, 14 Jun 2022 09:58:54 +0800 Subject: [PATCH 08/28] https://github.com/topcoder-platform/topcoder-x-ui/issues/459 --- services/NotificationService.js | 56 +++++++++++++++++++++++++++++++++ utils/kafka-consumer.js | 7 +++++ utils/notification.js | 17 ++++++++-- 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 services/NotificationService.js diff --git a/services/NotificationService.js b/services/NotificationService.js new file mode 100644 index 0000000..76d2c9d --- /dev/null +++ b/services/NotificationService.js @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 TopCoder, Inc. All rights reserved. + */ +'use strict'; + +/** + * This service processes incoming pure challenge events. + * + * @author TCSCODER + * @version 1.0 + */ +const Joi = require('joi'); +const logger = require('../utils/logger'); +const notification = require('../utils/notification'); + +/** + * Send token expired notification + * @param {Object} event the event + */ +async function handleTokenExpired(event) { + try { + const {copilotHandle, provider} = event.data; + await notification.sendTokenExpiredAlert(copilotHandle, '', provider); + logger.debug('Send token expired notification success'); + } catch (err) { + logger.debug(`Send token expired notification failed. Internal Error: ${err}`); + } +} + +/** + * Process notification event. + * @param {Object} event the event + */ +async function process(event) { + Joi.attempt(event, process.schema); + + if (event.event === 'notification.tokenExpired') { + await handleTokenExpired(event); + } +} + +process.schema = Joi.object().keys({ + event: Joi.string().valid('notification.tokenExpired').required(), + data: Joi.object().keys({ + copilotHandle: Joi.string().required(), + provider: Joi.string().required() + }).required(), + retryCount: Joi.number().integer().default(0).optional() +}); + + +module.exports = { + process +}; + +logger.buildService(module.exports); diff --git a/utils/kafka-consumer.js b/utils/kafka-consumer.js index c0e6fc5..30655a7 100644 --- a/utils/kafka-consumer.js +++ b/utils/kafka-consumer.js @@ -13,6 +13,7 @@ const healthcheck = require('topcoder-healthcheck-dropin'); const IssueService = require('../services/IssueService'); const CopilotPaymentService = require('../services/CopilotPaymentService'); const ChallengeService = require('../services/ChallengeService'); +const NotificationService = require('../services/NotificationService'); const logger = require('./logger'); const kafka = require('./kafka'); @@ -54,6 +55,12 @@ function messageHandler(messageSet) { .process(event) .catch(logger.error); } + if (event && _.includes(['notification.tokenExpired'] + , event.event)) { + NotificationService + .process(event) + .catch(logger.error); + } }); } diff --git a/utils/notification.js b/utils/notification.js index ad9a8fa..f294275 100644 --- a/utils/notification.js +++ b/utils/notification.js @@ -15,12 +15,25 @@ const logger = require('./logger'); const notification = {}; -const content = `Hi {handle}, -You made an update to ticket {link}, but Topcoder-X couldn't process it properly because your {provider} token has expired. To fix this, please login to x.topcoder.com, click your handle in the upper right and then "Settings" to refresh your token. You will need to redo the action that failed in {provider}.`; // eslint-disable-line max-len +/** + * get content template to send + * @param {String} repoPath the repo path + * @returns {String} + */ +function getContent(repoPath) { + return repoPath + ? + `Hi {handle}, + You made an update to ticket {link}, but Topcoder-X couldn't process it properly because your {provider} token has expired. To fix this, please login to x.topcoder.com, click your handle in the upper right and then "Settings" to refresh your token. You will need to redo the action that failed in {provider}.` // eslint-disable-line max-len + : + `Hi {handle}, + You made an operation on {provider}, but Topcoder-X couldn't process it properly because your {provider} token has expired. To fix this, please login to x.topcoder.com, click your handle in the upper right and then "Settings" to refresh your token. You will need to redo the action that failed in {provider}.`; // eslint-disable-line max-len +} notification.sendTokenExpiredAlert = async function sendTokenExpiredAlert(copilotHandle, repoPath, provider) { const copilotId = await topcoderApiHelper.getTopcoderMemberId(copilotHandle); const notificationConfigs = config.MAIL_NOTICIATION; + const content = getContent(repoPath); logger.debug(`Sending mail notification to copilot ${copilotHandle} Repo: ${repoPath} Provider: ${provider}`); await kafkaSender.sendNotification({ serviceId: 'email', From 9646e18c2e85f09dd844fb39bf02bb691a09cda0 Mon Sep 17 00:00:00 2001 From: Gunasekar-K Date: Wed, 24 May 2023 16:29:18 +0530 Subject: [PATCH 09/28] read-only-root-file-system-fix --- .circleci/config.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 59f2db2..a49ecbc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,17 +1,19 @@ version: 2 defaults: &defaults docker: - - image: circleci/python:2.7-stretch-browsers + - image: cimg/python:3.11.0-browsers install_dependency: &install_dependency name: Installation of build and deployment dependencies. command: | + sudo apt update sudo apt install jq - sudo pip install awscli --upgrade - sudo pip install docker-compose + sudo apt install python3-pip + sudo pip3 install awscli --upgrade + sudo pip3 install docker-compose install_deploysuite: &install_deploysuite name: Installation of install_deploysuite. command: | - git clone --branch v1.4.1 https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript + git clone --branch v1.4.15 https://github.com/topcoder-platform/tc-deploy-scripts ../buildscript cp ./../buildscript/master_deploy.sh . cp ./../buildscript/buildenv.sh . cp ./../buildscript/awsconfiguration.sh . @@ -75,4 +77,4 @@ workflows: context : org-global filters: branches: - only: master \ No newline at end of file + only: master From b95aa4b04360b3a46b49578550975132a760699d Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Fri, 25 Aug 2023 04:11:33 +0530 Subject: [PATCH 10/28] For #469: Create private fork when users register --- .eslintrc | 8 +- .gitignore | 3 + config/default.js | 3 +- constants.js | 12 +- docker/Dockerfile | 16 +- models/ProjectChallengeMapping.js | 34 + models/index.js | 1 + package-lock.json | 7874 +++++++++++++++++++---------- package.json | 4 +- services/GitlabService.js | 87 +- services/PrivateForkService.js | 126 + utils/db-helper.js | 173 +- utils/errors.js | 24 +- utils/kafka-consumer.js | 107 +- utils/kafka-sender.js | 4 +- 15 files changed, 5714 insertions(+), 2762 deletions(-) create mode 100644 models/ProjectChallengeMapping.js create mode 100644 services/PrivateForkService.js diff --git a/.eslintrc b/.eslintrc index a5406e2..a16e9ea 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,6 +3,9 @@ "node": true, "mocha": true }, + "plugins": [ + "jsdoc" + ], "parserOptions": { "ecmaVersion": 8, "ecmaFeatures": { @@ -43,6 +46,7 @@ } ], "max-lines": 0, - "max-statements": 0 + "max-statements": 0, + "valid-jsdoc": 0 } -} \ No newline at end of file +} diff --git a/.gitignore b/.gitignore index d2409da..f45e38d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ *.cer *.key .idea + +.env +.envrc diff --git a/config/default.js b/config/default.js index e17d3f4..68d4216 100644 --- a/config/default.js +++ b/config/default.js @@ -16,11 +16,12 @@ module.exports = { LOG_LEVEL: process.env.LOG_LEVEL || 'debug', PARTITION: process.env.PARTITION || 0, TOPIC: process.env.TOPIC || 'tc-x-events', + TOPIC_CHALLENGE_ACTION_RESOURCE_CREATE: process.env.TOPIC_CHALLENGE_ACTION_RESOURCE_CREATE || 'challenge.action.resource.create', TOPIC_NOTIFICATION: process.env.TOPIC_NOTIFICATION || 'notifications.action.create', KAFKA_OPTIONS: { connectionString: process.env.KAFKA_URL || 'localhost:9092', groupId: process.env.KAFKA_GROUP_ID || 'topcoder-x-processor', - ssl: { + ssl: process.env.KAFKA_DISABLE_SSL ? false : { cert: process.env.KAFKA_CLIENT_CERT || fs.readFileSync('./kafka_client.cer'), // eslint-disable-line no-sync key: process.env.KAFKA_CLIENT_CERT_KEY || fs.readFileSync('./kafka_client.key'), // eslint-disable-line no-sync passphrase: 'secret', // NOTE:* This configuration specifies the private key passphrase used while creating it. diff --git a/constants.js b/constants.js index 187c5c4..cb32c76 100644 --- a/constants.js +++ b/constants.js @@ -43,10 +43,20 @@ const ISSUE_STATUS = { CHALLENGE_PAYMENT_FAILED: 'challenge_payment_failed' }; +const GITLAB_ACCESS_LEVELS = { + NO_ACCESS: 0, + GUEST: 10, + REPORTER: 20, + DEVELOPER: 30, + MAINTAINER: 40, + OWNER: 50 +}; + module.exports = { USER_ROLES, USER_TYPES, SERVICE_ERROR_STATUS, CHALLENGE_STATUS, - ISSUE_STATUS + ISSUE_STATUS, + GITLAB_ACCESS_LEVELS }; diff --git a/docker/Dockerfile b/docker/Dockerfile index 29eb298..42a33a8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,15 +1,9 @@ # Use the base image with Node.js -FROM node:8.12 +FROM node:20 -# Copy the current directory into the Docker image -COPY . /topcoder-x-processor - -# Set working directory for future use WORKDIR /topcoder-x-processor +COPY package.json package-lock.json ./ +RUN npm ci --silent --legacy-peer-deps +COPY . . -# Install the dependencies from package.json -RUN npm install -#RUN npm run build -#RUN npm run test - -CMD npm start \ No newline at end of file +CMD npm start diff --git a/models/ProjectChallengeMapping.js b/models/ProjectChallengeMapping.js new file mode 100644 index 0000000..5b4c585 --- /dev/null +++ b/models/ProjectChallengeMapping.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 TopCoder, Inc. All rights reserved. + */ +'use strict'; + +/** + * This defines TCX project to TC challenge mapping model. + */ +const dynamoose = require('dynamoose'); + +const Schema = dynamoose.Schema; + +const schema = new Schema({ + id: { + type: String, + required: true, + hashKey: true + }, + projectId: { + type: String, + required: true, + index: { + global: true, + project: true, + name: 'ProjectIdIndex' + } + }, + challengeId: { + type: String, + required: true + } +}); + +module.exports = schema; diff --git a/models/index.js b/models/index.js index 2c88f37..4d8dbc1 100644 --- a/models/index.js +++ b/models/index.js @@ -37,6 +37,7 @@ if (process.env.CREATE_DB) { const models = { Issue: dynamoose.model('Topcoder_X.Issue', require('./Issue')), Project: dynamoose.model('Topcoder_X.Project', require('./Project')), + ProjectChallengeMapping: dynamoose.model('Topcoder_X.ProjectChallengeMapping', require('./ProjectChallengeMapping')), User: dynamoose.model('Topcoder_X.User', require('./User')), CopilotPayment: dynamoose.model('Topcoder_X.CopilotPayment', require('./CopilotPayment')), GithubUserMapping: dynamoose.model('Topcoder_X.GithubUserMapping', require('./GithubUserMapping')), diff --git a/package-lock.json b/package-lock.json index 4355858..74bde4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,490 +1,1123 @@ { "name": "processor", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/runtime": { - "version": "7.0.0-beta.51", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-beta.51.tgz", - "integrity": "sha1-SLjtGDBwNMZiD2Q1FGUMoszAFlo=", - "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" - } - }, - "@gimenete/type-writer": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@gimenete/type-writer/-/type-writer-0.1.3.tgz", - "integrity": "sha512-vhpvVfM/fYqb1aAnkgOvtDKoOgU3ZYIvDnKSDAFSoBvallmGURMlHOE0/VG/gqunUZVXGCFBGHxI8swjBh+sIA==", - "dev": true, - "requires": { - "camelcase": "5.0.0", - "prettier": "1.14.2" - } - }, - "@octokit/rest": { - "version": "15.10.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.10.0.tgz", - "integrity": "sha512-xZ4ejCZoqvKrIN3tQOKZlJ6nDQxaOdLcjRsamDnbckU7V5YTn2xheIqFXnQ2vLvxqVwyI8+2dfsODYbHxtwtSw==", - "dev": true, - "requires": { - "@gimenete/type-writer": "0.1.3", - "before-after-hook": "1.1.0", - "btoa-lite": "1.0.0", - "debug": "3.1.0", - "http-proxy-agent": "2.1.0", - "https-proxy-agent": "2.2.4", - "lodash": "4.17.21", - "node-fetch": "2.6.1", - "url-template": "2.0.8" + "packages": { + "": { + "name": "processor", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@gitbeaker/rest": "^39.12.0", + "@octokit/rest": "^18.9.0", + "axios": "^0.19.0", + "circular-json": "^0.5.7", + "config": "^1.30.0", + "dynamoose": "^1.11.1", + "fs-extra": "^7.0.0", + "get-parameter-names": "^0.3.0", + "global-request-logger": "^0.1.1", + "joi": "^13.4.0", + "jwt-decode": "^2.2.0", + "lodash": "^4.17.13", + "markdown-it": "^8.4.1", + "moment": "^2.22.2", + "no-kafka": "^3.2.10", + "nodemailer": "^4.6.7", + "superagent": "^3.6.0", + "superagent-promise": "^1.1.0", + "tc-core-library-js": "appirio-tech/tc-core-library-js.git#v2.6.3", + "topcoder-healthcheck-dropin": "^1.0.3", + "util": "^0.11.0", + "validator": "^13.0.0", + "winston": "^2.4.3" + }, + "devDependencies": { + "chai": "^4.1.2", + "eslint": "^8.47.0", + "eslint-config-topcoder": "^2.0.0", + "eslint-plugin-babel": "^4.1.2", + "eslint-plugin-chai-expect": "^1.1.1", + "eslint-plugin-jsdoc": "^46.5.0", + "eslint-plugin-react": "^7.10.0", + "gitlab": "^3.7.0", + "mocha": "^5.2.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": "~8.6.0" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz", + "integrity": "sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg==", + "dev": true, + "dependencies": { + "comment-parser": "1.4.0", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz", + "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@gitbeaker/core": { + "version": "39.12.0", + "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-39.12.0.tgz", + "integrity": "sha512-c/LQl+UI+rXjXx+P+kLrdTOZnyD/RdhRWnkuBE8b8/dwfvnJ3ANEv1WBZhVJpTwn6miHlurERiOeLmKeQJ+J6w==", + "dependencies": { + "@gitbeaker/requester-utils": "^39.12.0", + "qs": "^6.11.2", + "xcase": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@gitbeaker/core/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@gitbeaker/requester-utils": { + "version": "39.12.0", + "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-39.12.0.tgz", + "integrity": "sha512-0016Xnt6xIO3kSUuJ/mcXyN8LWUMpqAmLFbXZWMzJ9YZpQHX9vPKsrFHz4/P9Dh9eWKoAnkjEXEf/F6w1gX6Dg==", + "dependencies": { + "qs": "^6.11.2", + "xcase": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@gitbeaker/requester-utils/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@gitbeaker/rest": { + "version": "39.12.0", + "resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-39.12.0.tgz", + "integrity": "sha512-PILr042hCuB/A/QE7IGQ0ADTMN1e8lvehEfZEQEp78aWlqyNFmi6IUZqL6q8v3Stu6WRKSRcMCOidY83hiCSsA==", + "dependencies": { + "@gitbeaker/core": "^39.12.0", + "@gitbeaker/requester-utils": "^39.12.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", + "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", + "dependencies": { + "@octokit/types": "^6.40.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", + "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", + "dependencies": { + "@octokit/types": "^6.39.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dependencies": { + "@octokit/openapi-types": "^12.11.0" } }, - "@semantic-release/error": { + "node_modules/@semantic-release/error": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", "dev": true }, - "@semantic-release/npm": { + "node_modules/@semantic-release/npm": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-4.0.2.tgz", "integrity": "sha512-7uzMkY4IDN4tFTy3/zAsHPveW1fxXo4ORALaVqdopkCBGLhLtthf4TyWvJVaiS+LsBpgMer/vcwIpv5k58IUzA==", "dev": true, - "requires": { - "@semantic-release/error": "2.2.0", - "aggregate-error": "1.0.0", - "detect-indent": "5.0.0", - "detect-newline": "2.1.0", - "execa": "0.10.0", - "fs-extra": "7.0.0", - "lodash": "4.17.21", - "nerf-dart": "1.0.0", - "normalize-url": "3.2.0", - "parse-json": "4.0.0", - "rc": "1.2.8", - "read-pkg": "4.0.1", - "registry-auth-token": "3.3.2" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "1.3.1", - "json-parse-better-errors": "1.0.2" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", - "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", - "dev": true, - "requires": { - "normalize-package-data": "2.4.0", - "parse-json": "4.0.0", - "pify": "3.0.0" - } - } + "dependencies": { + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^1.0.0", + "detect-indent": "^5.0.0", + "detect-newline": "^2.1.0", + "execa": "^0.10.0", + "fs-extra": "^7.0.0", + "lodash": "^4.17.4", + "nerf-dart": "^1.0.0", + "normalize-url": "^3.0.0", + "parse-json": "^4.0.0", + "rc": "^1.2.8", + "read-pkg": "^4.0.0", + "registry-auth-token": "^3.3.1" + }, + "engines": { + "node": ">=8.3" + }, + "peerDependencies": { + "semantic-release": ">=15.8.0 <16.0.0" + } + }, + "node_modules/@semantic-release/npm/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@semantic-release/npm/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" } }, - "@tootallnate/once": { + "node_modules/@semantic-release/npm/node_modules/read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "dependencies": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } }, - "@types/bluebird": { + "node_modules/@types/bluebird": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.0.tgz", "integrity": "sha1-JjNHCk6r6aR82aRf2yDtX5NAe8o=" }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "3.4.34", - "@types/node": "11.11.0" + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" } }, - "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "requires": { - "@types/node": "11.11.0" + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dependencies": { + "@types/node": "*" } }, - "@types/express": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", - "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", - "requires": { - "@types/body-parser": "1.19.0", - "@types/express-serve-static-core": "4.17.19", - "@types/qs": "6.9.6", - "@types/serve-static": "1.13.9" + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "@types/express-jwt": { + "node_modules/@types/express-jwt": { "version": "0.0.42", "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", - "requires": { - "@types/express": "4.17.11", - "@types/express-unless": "0.5.1" + "dependencies": { + "@types/express": "*", + "@types/express-unless": "*" } }, - "@types/express-serve-static-core": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", - "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", - "requires": { - "@types/node": "11.11.0", - "@types/qs": "6.9.6", - "@types/range-parser": "1.2.3" + "node_modules/@types/express-serve-static-core": { + "version": "4.17.35", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", + "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "@types/express-unless": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", - "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", - "requires": { - "@types/express": "4.17.11" + "node_modules/@types/express-unless": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-2.0.1.tgz", + "integrity": "sha512-PJLiNw03EjkWDkQbhNjIXXDLObC3eMQhFASDV+WakFbT8eL7YdjlbV6MXd3Av5Lejq499d6pFuV1jyK+EHyG3Q==", + "deprecated": "This is a stub types definition. express-unless provides its own type definitions, so you do not need this installed.", + "dependencies": { + "express-unless": "*" } }, - "@types/lodash": { + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" + }, + "node_modules/@types/lodash": { "version": "4.14.110", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.110.tgz", "integrity": "sha512-iXYLa6olt4tnsCA+ZXeP6eEW3tk1SulWeYyP/yooWfAtXjozqXgtX4+XUtMuOCfYjKGz3F34++qUc3Q+TJuIIw==" }, - "@types/mime": { + "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, - "@types/node": { + "node_modules/@types/node": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.0.tgz", "integrity": "sha512-D5Rt+HXgEywr3RQJcGlZUCTCx1qVbCZpVk3/tOOA6spLNZdGm8BU+zRgdRYDoF1pO3RuXLxADzMrF903JlQXqg==" }, - "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } }, - "@types/serve-static": { - "version": "1.13.9", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", - "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", - "requires": { - "@types/mime": "1.3.2", - "@types/node": "11.11.0" + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" } }, - "accepts": { + "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "2.1.24", + "dependencies": { + "mime-types": "~2.1.24", "negotiator": "0.6.2" }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", "dependencies": { - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - } + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" } }, - "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", - "dev": true + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "requires": { - "acorn": "3.3.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "5.0.0" - } + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "aggregate-error": { + "node_modules/aggregate-error": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-1.0.0.tgz", "integrity": "sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w=", "dev": true, - "requires": { - "clean-stack": "1.3.0", - "indent-string": "3.2.0" + "dependencies": { + "clean-stack": "^1.0.0", + "indent-string": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "ajv": { + "node_modules/ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "dev": true, + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, - "ajv-keywords": { + "node_modules/ajv-keywords": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true + "integrity": "sha512-vuBv+fm2s6cqUyey2A7qYcvsik+GMDJsw8BARP2sDE76cqmaZVarsvHf7Vx6VJ0Xk8gLl+u3MoAPf6gKzJefeA==", + "dev": true, + "peerDependencies": { + "ajv": ">=4.10.0" + } }, - "ansi-escapes": { + "node_modules/ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "argparse": { + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "requires": { - "sprintf-js": "1.0.3" + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "array-flatten": { + "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "array-includes": { + "node_modules/array-includes": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.12.0" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + }, + "engines": { + "node": ">= 0.4" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, - "asn1": { + "node_modules/asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, - "assert-plus": { + "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } }, - "assertion-error": { + "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "asynckit": { + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "auth0-js": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.16.0.tgz", - "integrity": "sha512-I9jECErKZviVPVg0hKfG7URiGV/woyd0JOnh1SKH7Vy4/9n+AkJXgZqF7ayGV5W8sHKJl2aZ3ve3fc50LfR07g==", - "requires": { - "base64-js": "1.3.1", - "idtoken-verifier": "2.1.0", - "js-cookie": "2.2.1", - "qs": "6.10.1", - "superagent": "5.3.1", - "url-join": "4.0.1", - "winchan": "0.2.2" - }, - "dependencies": { - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "node_modules/auth0-js": { + "version": "9.22.1", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.22.1.tgz", + "integrity": "sha512-AcyJiWhsyG5zdx40O9i/okpLLEvB23/6CivWynmGtP43s2C4GSq3E+XdCRw64ifmZ7t6ZK4Yzfpiqy5KVXEtJg==", + "dependencies": { + "base64-js": "^1.5.1", + "idtoken-verifier": "^2.2.2", + "js-cookie": "^2.2.0", + "minimist": "^1.2.5", + "qs": "^6.10.1", + "superagent": "^7.1.5", + "url-join": "^4.0.1", + "winchan": "^0.2.2" + } + }, + "node_modules/auth0-js/node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/auth0-js/node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/auth0-js/node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/auth0-js/node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" + }, + "node_modules/auth0-js/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/auth0-js/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/auth0-js/node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/auth0-js/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/auth0-js/node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/auth0-js/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/auth0-js/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/auth0-js/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/auth0-js/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "superagent": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz", - "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", - "requires": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.2", - "debug": "^4.1.1", - "fast-safe-stringify": "^2.0.7", - "form-data": "^3.0.0", - "formidable": "^1.2.2", - "methods": "^1.1.2", - "mime": "^2.4.6", - "qs": "^6.9.4", - "readable-stream": "^3.6.0", - "semver": "^7.3.2" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/auth0-js/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/auth0-js/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/auth0-js/node_modules/superagent": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-7.1.5.tgz", + "integrity": "sha512-HQYyGuDRFGmZ6GNC4hq2f37KnsY9Lr0/R1marNZTgMweVDQLTLJJ6DGQ9Tj/xVVs5HEnop9EMmTbywb5P30aqw==", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.3", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^2.0.1", + "methods": "^1.1.2", + "mime": "^2.5.0", + "qs": "^6.10.3", + "readable-stream": "^3.6.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=6.4.0 <13 || >=14" } }, - "aws-sdk": { + "node_modules/auth0-js/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "node_modules/aws-sdk": { "version": "2.395.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.395.0.tgz", "integrity": "sha512-ldTTjctniZT4E2lq2z3D8Y2u+vpkp+laoEnDkXgjKXTKbiJ0QEtfWsUdx/IQ7awCt8stoxyqZK47DJOxIbRNoA==", - "requires": { + "dependencies": { "buffer": "4.9.1", "events": "1.1.1", "ieee754": "1.1.8", @@ -494,596 +1127,809 @@ "url": "0.10.3", "uuid": "3.3.2", "xml2js": "0.4.19" + }, + "engines": { + "node": ">= 0.8.0" } }, - "aws-sign2": { + "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } }, - "aws4": { + "node_modules/aws4": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "dev": true }, - "axios": { + "node_modules/axios": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "requires": { + "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "dependencies": { "follow-redirects": "1.5.10", - "is-buffer": "2.0.3" + "is-buffer": "^2.0.2" } }, - "babel-code-frame": { + "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "engines": { + "node": ">=0.8.0" } }, - "babel-runtime": { + "node_modules/babel-runtime": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.6.1.tgz", - "integrity": "sha1-eIuUtvY04luRvWxd9y1GdFevsAA=", - "requires": { - "core-js": "2.5.7" + "integrity": "sha512-5pdhO3jaxqh9L42oBfbrqy58swDhciM47sRGoODURdRxwfiqttEvK87LX27W/PYY6f4cJt2mEdyoLcr/+cM/iw==", + "dependencies": { + "core-js": "^2.1.0" } }, - "backoff": { + "node_modules/backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", - "requires": { - "precond": "0.2.3" + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "devOptional": true }, - "base64-js": { + "node_modules/base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, - "bcrypt-pbkdf": { + "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "optional": true, - "requires": { - "tweetnacl": "0.14.5" + "dependencies": { + "tweetnacl": "^0.14.3" } }, - "before-after-hook": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", - "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==", - "dev": true + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" }, - "bin-protocol": { + "node_modules/bin-protocol": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/bin-protocol/-/bin-protocol-3.0.4.tgz", "integrity": "sha1-RlqdNQb+sOEmtStbIWDZNuFbJ/Q=", - "requires": { - "lodash": "4.17.21", - "long": "3.2.0", - "protocol-buffers-schema": "3.3.2" - }, "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - } + "lodash": "^4.1.0", + "long": "^3.0.3", + "protocol-buffers-schema": "^3.0.0" } }, - "bluebird": { + "node_modules/bin-protocol/node_modules/long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" }, - "body-parser": { + "node_modules/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { + "dependencies": { "bytes": "3.1.0", - "content-type": "1.0.4", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", + "depd": "~1.1.2", "http-errors": "1.7.2", "iconv-lite": "0.4.24", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.7.0", "raw-body": "2.4.0", - "type-is": "1.6.18" + "type-is": "~1.6.17" }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" } }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", + "devOptional": true, + "dependencies": { + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "browser-stdout": { + "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=", - "dev": true - }, - "buffer": { + "node_modules/buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { - "base64-js": "1.3.1", - "ieee754": "1.1.8", - "isarray": "1.0.0" + "deprecated": "This version of 'buffer' is out-of-date. You must update to v4.9.2 or newer", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, - "buffer-crc32": { + "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "engines": { + "node": "*" + } }, - "buffer-equal-constant-time": { + "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, - "builtin-modules": { + "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "bunyan": { + "node_modules/bunyan": { "version": "1.8.15", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", - "requires": { - "dtrace-provider": "0.8.8", - "moment": "2.22.2", - "mv": "2.1.1", - "safe-json-stringify": "1.2.0" + "engines": [ + "node >=0.10.0" + ], + "bin": { + "bunyan": "bin/bunyan" + }, + "optionalDependencies": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" } }, - "bytes": { + "node_modules/bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } }, - "call-bind": { + "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "1.1.1", - "get-intrinsic": "1.1.1" + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "caller-path": { + "node_modules/caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", "dev": true, - "requires": { - "callsites": "0.2.0" + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "callsites": { + "node_modules/caller-path/node_modules/callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true + "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "caseless": { + "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "chai": { + "node_modules/chai": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, - "requires": { - "assertion-error": "1.1.0", - "check-error": "1.0.2", - "deep-eql": "3.0.1", - "get-func-name": "2.0.0", - "pathval": "1.1.0", - "type-detect": "4.0.8" + "dependencies": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=4" } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "check-error": { + "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "circular-json": { + "node_modules/circular-json": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.7.tgz", - "integrity": "sha512-/pXoV1JA847qRKPrHbBK6YIBGFF8GOP4wzSgUOA7q0ew0vAv0iJswP+2/nZQ9uzA3Azi7eTrg9L2yzXc/7ZMIA==" + "integrity": "sha512-/pXoV1JA847qRKPrHbBK6YIBGFF8GOP4wzSgUOA7q0ew0vAv0iJswP+2/nZQ9uzA3Azi7eTrg9L2yzXc/7ZMIA==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "hasInstallScript": true }, - "clean-stack": { + "node_modules/clean-stack": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "cli-cursor": { + "node_modules/cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", "dev": true, - "requires": { - "restore-cursor": "1.0.1" + "dependencies": { + "restore-cursor": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, - "co": { + "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "code-point-at": { + "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "codependency": { + "node_modules/codependency": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/codependency/-/codependency-0.1.4.tgz", - "integrity": "sha1-0XY6tyZL1wyR2WJumIYtN5K/jUo=", - "requires": { + "integrity": "sha512-26yAvd3+17xSfDADtnzpnL5GK+8+x4QeZ3DegekkHyno6LWeHqXuSU7q8w/IrAur7SY6ISPApOWtWTfuIF0Xpg==", + "dependencies": { "semver": "5.0.1" - }, + } + }, + "node_modules/codependency/node_modules/semver": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.1.tgz", + "integrity": "sha512-Ne6/HdGZvvpXBdjW3o8J0pvxC2jnmVNBK7MKkMgsOBfrsIdTXfA5x+H9DUbQ2xzyvnLv0A0v9x8R4B40xNZIRQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "semver": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.1.tgz", - "integrity": "sha1-n7P0AE+QDYPEeWj+QvdYPgWDLMk=" - } + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "colors": { + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "engines": { + "node": ">=0.1.90" + } }, - "combined-stream": { + "node_modules/combined-stream": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "requires": { - "delayed-stream": "1.0.0" + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "commander": { + "node_modules/commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, - "component-emitter": { + "node_modules/comment-parser": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.0.tgz", + "integrity": "sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "devOptional": true }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "config": { + "node_modules/config": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/config/-/config-1.30.0.tgz", "integrity": "sha1-HWCp81NIoTwXV5jThOgaWhbDum4=", - "requires": { + "dependencies": { "json5": "0.4.0", "os-homedir": "1.0.2" + }, + "engines": { + "node": ">= 4.0.0" } }, - "connection-parse": { + "node_modules/connection-parse": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/connection-parse/-/connection-parse-0.0.7.tgz", "integrity": "sha1-GOcxiqsGppkmc3KxDFIm0locmmk=" }, - "contains-path": { + "node_modules/contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "content-disposition": { + "node_modules/content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { + "dependencies": { "safe-buffer": "5.1.2" }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } + "engines": { + "node": ">= 0.6" } }, - "content-type": { + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } }, - "cookie": { + "node_modules/cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } }, - "cookie-signature": { + "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "cookiejar": { + "node_modules/cookiejar": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" }, - "core-js": { + "node_modules/core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js." }, - "core-util-is": { + "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, - "requires": { - "nice-try": "1.0.4", - "path-key": "2.0.1", - "semver": "5.5.0", - "shebang-command": "1.2.0", - "which": "1.3.1" - }, "dependencies": { - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - } + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" } }, - "crypto-js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", - "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true, + "bin": { + "semver": "bin/semver" + } }, - "cycle": { + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, + "node_modules/cycle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", + "engines": { + "node": ">=0.4.0" + } }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, - "requires": { - "es5-ext": "0.10.30" + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" } }, - "dashdash": { + "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" } }, - "debug": { + "node_modules/debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { + "dependencies": { "ms": "2.0.0" } }, - "deep-eql": { + "node_modules/deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, - "requires": { - "type-detect": "4.0.8" + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" } }, - "deep-equal": { + "node_modules/deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" }, - "deep-extend": { + "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.0.0" + } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "define-properties": { + "node_modules/define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "dev": true, - "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.12" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" + "dependencies": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + }, + "engines": { + "node": ">= 0.4" } }, - "delayed-stream": { + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } }, - "depd": { + "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } }, - "destroy": { + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, - "detect-indent": { + "node_modules/detect-indent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "detect-newline": { + "node_modules/detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } }, - "diff": { + "node_modules/diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.3.1" + } }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "dom-walk": { + "node_modules/dom-walk": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", "dev": true }, - "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" - }, - "dtrace-provider": { + "node_modules/dtrace-provider": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", + "hasInstallScript": true, "optional": true, - "requires": { - "nan": "2.14.2" + "dependencies": { + "nan": "^2.14.0" + }, + "engines": { + "node": ">=0.10" } }, - "dynamoose": { + "node_modules/dynamoose": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/dynamoose/-/dynamoose-1.11.1.tgz", "integrity": "sha512-73T0GOeSh2FQDdK5V+cN9yowFU4uVt2OsOvknCB4Xdb+nSL/hBaecPY/meJaWZApVx73Hl1DcBSCGp/VWMvfRA==", - "requires": { + "dependencies": { "@types/node": "11.11.0", "aws-sdk": "2.395.0", "debug": "4.1.1", @@ -1092,1584 +1938,2755 @@ "object-path": "0.11.4", "q": "1.5.1" }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/dynamoose/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } + "ms": "^2.1.1" } }, - "ecc-jsbn": { + "node_modules/dynamoose/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", "optional": true, - "requires": { - "jsbn": "0.1.1" + "dependencies": { + "jsbn": "~0.1.0" } }, - "ecdsa-sig-formatter": { + "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "5.1.1" + "dependencies": { + "safe-buffer": "^5.0.1" } }, - "ee-first": { + "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, - "encodeurl": { + "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } }, - "entities": { + "node_modules/entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, - "error-ex": { + "node_modules/error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, - "requires": { - "is-arrayish": "0.2.1" + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "es-abstract": { + "node_modules/es-abstract": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", "dev": true, - "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" + "dependencies": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" } }, - "es-to-primitive": { + "node_modules/es-to-primitive": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "dev": true, - "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" + "dependencies": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "es5-ext": { - "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, - "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" } }, - "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-symbol": "3.1.1" + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, - "es6-map": { + "node_modules/es6-map": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "integrity": "sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "4.2.4" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/es6-set": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.6.tgz", + "integrity": "sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "es6-iterator": "~2.0.3", + "es6-symbol": "^3.1.3", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" } }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "node_modules/es6-set/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" } }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" } }, - "escape-html": { + "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "escope": { + "node_modules/escope": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "integrity": "sha512-75IUQsusDdalQEW/G/2esa87J7raqdJF+Ca0/Xm5C3Q58Nr4yVYjZGp/P1+2xiEVgXRrA39dpRb8LcshajbqDQ==", + "dev": true, + "dependencies": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/escope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-topcoder": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-topcoder/-/eslint-config-topcoder-2.0.0.tgz", + "integrity": "sha1-V+swpLHETyCdXSUn/NdYWH28Rj0=", "dev": true, - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" + "dependencies": { + "eslint": "^3.12.0", + "eslint-plugin-import": "^2.2.0", + "eslint-plugin-lodash": "^2.2.4" + }, + "peerDependencies": { + "babel-eslint": "^7.1.1", + "eslint-plugin-babel": "^4.0.0", + "eslint-plugin-react": "^6.8.0" } }, - "eslint": { + "node_modules/eslint-config-topcoder/node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", + "dev": true, + "dependencies": { + "acorn": "^3.0.4" + } + }, + "node_modules/eslint-config-topcoder/node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", + "dev": true + }, + "node_modules/eslint-config-topcoder/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/eslint": { "version": "3.19.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "integrity": "sha512-x6LJGXWCGB/4YOBhL48yeppZTo+YQUNC37N5qqCpC1b1kkNzydlQHQAtPuUSFoZSxgIadrysQoW2Hq602P+uEA==", "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.9", - "doctrine": "2.0.0", - "escope": "3.6.0", - "espree": "3.5.1", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.5", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.20.0", - "is-resolvable": "1.0.0", - "js-yaml": "3.13.1", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.21", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" + "dependencies": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.5.2", + "debug": "^2.1.1", + "doctrine": "^2.0.0", + "escope": "^3.6.0", + "espree": "^3.4.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-topcoder/node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "eslint-config-topcoder": { + "node_modules/eslint-config-topcoder/node_modules/file-entry-cache": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-topcoder/-/eslint-config-topcoder-2.0.0.tgz", - "integrity": "sha1-V+swpLHETyCdXSUn/NdYWH28Rj0=", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", + "dev": true, + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/eslint-config-topcoder/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint-config-topcoder/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-config-topcoder/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true, - "requires": { - "eslint": "3.19.0", - "eslint-plugin-import": "2.7.0", - "eslint-plugin-lodash": "2.4.5" + "engines": { + "node": ">= 0.8.0" } }, - "eslint-import-resolver-node": { + "node_modules/eslint-config-topcoder/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/eslint-config-topcoder/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-config-topcoder/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-config-topcoder/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint-import-resolver-node": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", "dev": true, - "requires": { - "debug": "2.6.9", - "resolve": "1.4.0" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "debug": "^2.6.8", + "resolve": "^1.2.0" } }, - "eslint-module-utils": { + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-module-utils": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", "dev": true, - "requires": { - "debug": "2.6.9", - "pkg-dir": "1.0.0" + "dependencies": { + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "ms": "2.0.0" } }, - "eslint-plugin-babel": { + "node_modules/eslint-plugin-babel": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-4.1.2.tgz", "integrity": "sha1-eSAqDjV1fdkngJGbIzbx+i/lPB4=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": ">=3.0.0" + } }, - "eslint-plugin-chai-expect": { + "node_modules/eslint-plugin-chai-expect": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-1.1.1.tgz", "integrity": "sha1-zWQLizjPbDq8w3hnO3sXO5ndxwo=", "dev": true }, - "eslint-plugin-import": { + "node_modules/eslint-plugin-import": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", "dev": true, - "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.9", + "dependencies": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.1", - "eslint-module-utils": "2.1.1", - "has": "1.0.1", - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">=4" }, + "peerDependencies": { + "eslint": "2.x - 4.x" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "46.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.5.0.tgz", + "integrity": "sha512-aulXdA4I1dyWpzyS1Nh/GNoS6PavzeucxEapnMR4JUERowWvaEk2Y4A5irpHAcdXtBBHLVe8WIhdXNjoAlGQgA==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.40.1", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.0", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.5.4", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "node_modules/eslint-plugin-lodash": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-2.4.5.tgz", + "integrity": "sha1-+drGSds6CNEjGOY1Ih68ROOE3F8=", + "dev": true, + "dependencies": { + "lodash": "~4.17.0" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "eslint": ">=2.10.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz", + "integrity": "sha512-18rzWn4AtbSUxFKKM7aCVcj5LXOhOKdwBino3KKWy4psxfPW0YtIbE8WNRDUdyHFL50BeLb6qFd4vpvNYyp7hw==", + "dev": true, + "dependencies": { + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "eslint-plugin-lodash": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-2.4.5.tgz", - "integrity": "sha1-+drGSds6CNEjGOY1Ih68ROOE3F8=", + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "requires": { - "lodash": "4.17.21" + "engines": { + "node": ">=8" } }, - "eslint-plugin-react": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz", - "integrity": "sha512-18rzWn4AtbSUxFKKM7aCVcj5LXOhOKdwBino3KKWy4psxfPW0YtIbE8WNRDUdyHFL50BeLb6qFd4vpvNYyp7hw==", + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { - "doctrine": "2.1.0", - "has": "1.0.3", - "jsx-ast-utils": "2.0.1", - "prop-types": "15.6.2" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "2.0.2" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "1.1.1" - } - } + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "espree": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", - "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "requires": { - "acorn": "5.1.2", - "acorn-jsx": "3.0.1" + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "requires": { - "estraverse": "4.2.0" + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" } }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "etag": { + "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } }, - "event-emitter": { + "node_modules/event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" } }, - "events": { + "node_modules/events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } }, - "execa": { + "node_modules/execa": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", "dev": true, - "requires": { - "cross-spawn": "6.0.5", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "exit-hook": { + "node_modules/exit-hook": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true + "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "express": { + "node_modules/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "1.3.7", + "dependencies": { + "accepts": "~1.3.7", "array-flatten": "1.1.1", "body-parser": "1.19.0", "content-disposition": "0.5.3", - "content-type": "1.0.4", + "content-type": "~1.0.4", "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.2", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.3", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.5", + "proxy-addr": "~2.0.5", "qs": "6.7.0", - "range-parser": "1.2.1", + "range-parser": "~1.2.1", "safe-buffer": "5.1.2", "send": "0.17.1", "serve-static": "1.14.1", "setprototypeof": "1.1.1", - "statuses": "1.5.0", - "type-is": "1.6.18", + "statuses": "~1.5.0", + "type-is": "~1.6.18", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-unless": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-2.1.3.tgz", + "integrity": "sha512-wj4tLMyCVYuIIKHGt0FhCtIViBcwzWejX0EjNxveAa6dG+0XBCQhMbx+PnkLkFCxLC69qoFrxds4pIyL88inaQ==" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" } }, - "extend": { + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, + "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "extsprintf": { + "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] }, - "eyes": { + "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } }, - "fast-deep-equal": { + "node_modules/fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, - "fast-levenshtein": { + "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } }, - "figures": { + "node_modules/figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "finalhandler": { + "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { + "dependencies": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.3", - "statuses": "1.5.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } + "ms": "2.0.0" } }, - "find-up": { + "node_modules/find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - }, "dependencies": { - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - } + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "follow-redirects": { + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "3.1.0" + "dependencies": { + "debug": "=3.1.0" }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/follow-redirects/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } + "ms": "2.0.0" } }, - "for-each": { + "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "requires": { - "is-callable": "1.1.3" + "dependencies": { + "is-callable": "^1.1.3" } }, - "foreach": { + "node_modules/foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, - "forever-agent": { + "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } }, - "form-data": { + "node_modules/form-data": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" } }, - "formidable": { + "node_modules/formidable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", - "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } }, - "forwarded": { + "node_modules/forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } }, - "fresh": { + "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } }, - "fs-extra": { + "node_modules/fs-extra": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz", "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.2" + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "dependencies": { + "is-property": "^1.0.2" + } }, - "generate-object-property": { + "node_modules/generate-object-property": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", "dev": true, - "requires": { - "is-property": "1.0.2" + "dependencies": { + "is-property": "^1.0.0" } }, - "get-func-name": { + "node_modules/get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "1.1.1", - "has": "1.0.3", - "has-symbols": "1.0.2" - }, - "dependencies": { - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "1.1.1" - } - } + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic/node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "get-parameter-names": { + "node_modules/get-parameter-names": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/get-parameter-names/-/get-parameter-names-0.3.0.tgz", - "integrity": "sha1-LSI3zVkubFuFmrLv2rQ18Ajlu5c=" + "integrity": "sha1-LSI3zVkubFuFmrLv2rQ18Ajlu5c=", + "engines": { + "node": ">= 0.4.0" + } }, - "get-stream": { + "node_modules/get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "getpass": { + "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "1.0.0" - } - }, - "github": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/github/-/github-12.1.0.tgz", - "integrity": "sha512-HhWjhd/OATC4Hjj7xfGjGRtwWzo/fzTc55EkvsRatI9G6Vp47mVcdBIt1lQ56A9Qit/yVQRX1+M9jbWlcJvgug==", - "requires": { - "dotenv": "4.0.0", - "follow-redirects": "1.2.6", - "https-proxy-agent": "2.2.4", - "lodash": "4.17.21", - "mime": "2.3.1", - "netrc": "0.1.4" - }, - "dependencies": { - "follow-redirects": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.6.tgz", - "integrity": "sha512-FrMqZ/FONtHnbqO651UPpfRUVukIEwJhXMfdr/JWAmrDbeYBu773b1J6gdWDyRIj4hvvzQEHoEOTrdR8o6KLYA==", - "requires": { - "debug": "3.1.0" - } - }, - "mime": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==" - } + "dependencies": { + "assert-plus": "^1.0.0" } }, - "gitlab": { + "node_modules/gitlab": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/gitlab/-/gitlab-3.7.0.tgz", "integrity": "sha512-MCPgNCVCUhOLzz6ZWBHyG6eyMAjiZdGEcGebWwFKPJR7N25y90rVXFJWBv6QfYKyPV8bNPFfxGLGwDJjtXUlkw==", + "deprecated": "The gitlab package has found a new home in the @gitbeaker organization. For the latest gitlab node library, check out @gitbeaker/node. A full list of the features can be found here: https://github.com/jdalrymple/gitbeaker#readme", "dev": true, - "requires": { - "@babel/runtime": "7.0.0-rc.1", - "@semantic-release/npm": "4.0.2", - "humps": "2.0.1", - "lodash.pick": "4.4.0", - "parse-link-header": "1.0.1", - "qs": "6.5.2", - "request": "2.87.0", - "request-promise": "4.2.2", - "request-promise-core": "1.1.1", - "url-join": "4.0.0", - "util.promisify": "1.0.0", - "xhr": "2.5.0" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-rc.1.tgz", - "integrity": "sha512-Nifv2kwP/nwR39cAOasNxzjYfpeuf/ZbZNtQz5eYxWTC9yHARU9wItFnAwz1GTZ62MU+AtSjzZPMbLK5Q9hmbg==", - "dev": true, - "requires": { - "regenerator-runtime": "0.12.1" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", - "dev": true - } + "dependencies": { + "@babel/runtime": "^7.0.0-beta.55", + "@semantic-release/npm": "^4.0.2", + "humps": "^2.0.1", + "lodash.pick": "^4.4.0", + "parse-link-header": "^1.0.1", + "qs": "^6.5.2", + "request": "^2.87.0", + "request-promise": "^4.2.2", + "request-promise-core": "^1.1.1", + "url-join": "^4.0.0", + "util.promisify": "^1.0.0", + "xhr": "^2.5.0" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/gitlab/node_modules/@babel/runtime": { + "version": "7.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0-rc.1.tgz", + "integrity": "sha512-Nifv2kwP/nwR39cAOasNxzjYfpeuf/ZbZNtQz5eYxWTC9yHARU9wItFnAwz1GTZ62MU+AtSjzZPMbLK5Q9hmbg==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.12.0" } }, - "glob": { + "node_modules/gitlab/node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/gitlab/node_modules/regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true + }, + "node_modules/glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, - "global": { + "node_modules/global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", "dev": true, - "requires": { - "min-document": "2.19.0", - "process": "0.5.2" + "dependencies": { + "min-document": "^2.19.0", + "process": "~0.5.1" } }, - "global-request-logger": { + "node_modules/global-request-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-request-logger/-/global-request-logger-0.1.1.tgz", "integrity": "sha1-g5oSZTcDHjO34awHdgi015lbAf4=", - "requires": { - "lodash": "2.4.2" - }, + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "engines": [ + "node" + ], "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" - } - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "lodash": "~2.4.1" + } + }, + "node_modules/global-request-logger/node_modules/lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "engines": [ + "node", + "rhino" + ] + }, + "node_modules/globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, - "growl": { + "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.x" + } }, - "har-schema": { + "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } }, - "har-validator": { + "node_modules/har-validator": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "has": { + "node_modules/has": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "dev": true, - "requires": { - "function-bind": "1.1.1" + "dependencies": { + "function-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.8.0" } }, - "has-ansi": { + "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, - "requires": { - "ansi-regex": "2.1.1" + "engines": { + "node": ">=0.10.0" } }, - "has-flag": { + "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "hashring": { + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hashring": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/hashring/-/hashring-3.2.0.tgz", "integrity": "sha1-/aTv3oqiLNuX+x0qZeiEAeHBRM4=", - "requires": { - "connection-parse": "0.0.7", - "simple-lru-cache": "0.0.2" + "dependencies": { + "connection-parse": "0.0.x", + "simple-lru-cache": "0.0.x" } }, - "he": { + "node_modules/he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true + "dev": true, + "bin": { + "he": "bin/he" + } }, - "hoek": { + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "engines": { + "node": ">=8" + } + }, + "node_modules/hoek": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.3.tgz", - "integrity": "sha512-Bmr56pxML1c9kU+NS51SMFkiVQAb+9uFfXwyqR2tn4w2FPvmPt65eZ9aCcEfRXd9G74HkZnILC6p967pED4aiw==" + "integrity": "sha512-Bmr56pxML1c9kU+NS51SMFkiVQAb+9uFfXwyqR2tn4w2FPvmPt65eZ9aCcEfRXd9G74HkZnILC6p967pED4aiw==", + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "engines": { + "node": ">=8.9.0" + } }, - "hooks": { + "node_modules/hooks": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/hooks/-/hooks-0.3.2.tgz", - "integrity": "sha1-ox8GDCAmzqbPHKPrF4Qw5xjhxKM=" + "integrity": "sha1-ox8GDCAmzqbPHKPrF4Qw5xjhxKM=", + "engines": { + "node": ">=0.4.0" + } }, - "hosted-git-info": { + "node_modules/hosted-git-info": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", "dev": true }, - "http-errors": { + "node_modules/http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "1.1.2", + "dependencies": { + "depd": "~1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.1", - "statuses": "1.5.0", + "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" } }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4.2.1", - "debug": "3.1.0" + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "http-signature": { + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.14.2" - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "4.3.0", - "debug": "3.1.0" - }, - "dependencies": { - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "5.0.0" - } + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "humps": { + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/humps": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/humps/-/humps-2.0.1.tgz", - "integrity": "sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao=" + "integrity": "sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao=", + "dev": true }, - "iconv-lite": { + "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": "2.1.2" + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "idtoken-verifier": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.1.0.tgz", - "integrity": "sha512-X0423UM4Rc5bFb39Ai0YHr35rcexlu4oakKdYzSGZxtoPy84P86hhAbzlpgbgomcLOFRgzgKRvhY7YjO5g8OPA==", - "requires": { - "base64-js": "1.3.1", - "crypto-js": "3.3.0", - "es6-promise": "4.2.8", - "jsbn": "1.1.0", - "unfetch": "4.2.0", - "url-join": "4.0.1" - }, - "dependencies": { - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "node_modules/idtoken-verifier": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.2.3.tgz", + "integrity": "sha512-hhpzB+MRgEvbwqzRLFdVbG55lKdXQVfeYEjAA2qu0UC72MSLeR0nX7P7rY5Dycz1aISHPOwq80hIPFoJ/+SItA==", + "dependencies": { + "base64-js": "^1.5.1", + "crypto-js": "^4.1.1", + "es6-promise": "^4.2.8", + "jsbn": "^1.1.0", + "unfetch": "^4.2.0", + "url-join": "^4.0.1" + } + }, + "node_modules/idtoken-verifier/node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA=" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + { + "type": "consulting", + "url": "https://feross.org/support" } - } + ] + }, + "node_modules/idtoken-verifier/node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" }, - "ieee754": { + "node_modules/idtoken-verifier/node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "node_modules/ieee754": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" }, - "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", - "dev": true + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "indent-string": { + "node_modules/indent-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "devOptional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "ini": { + "node_modules/ini": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true }, - "inquirer": { + "node_modules/inquirer": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "figures": "1.7.0", - "lodash": "4.17.21", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - } - }, - "interpret": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", - "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", - "dev": true + "integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "ipaddr.js": { + "node_modules/ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "engines": { + "node": ">= 0.10" + } }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-buffer": { + "node_modules/is-buffer": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "engines": { + "node": ">=4" + } }, - "is-builtin-module": { + "node_modules/is-builtin-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, - "requires": { - "builtin-modules": "1.1.1" + "dependencies": { + "builtin-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-callable": { + "node_modules/is-callable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "is-date-object": { + "node_modules/is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { + "node_modules/is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dev": true, - "requires": { - "number-is-nan": "1.0.1" + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-function": { + "node_modules/is-function": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", "dev": true }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz", - "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "is-my-ip-valid": "1.0.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "node_modules/is-my-ip-valid": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz", + "integrity": "sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==", "dev": true }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "node_modules/is-my-json-valid": { + "version": "2.20.6", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", + "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", "dev": true, - "requires": { - "is-path-inside": "1.0.0" + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^5.0.0", + "xtend": "^4.0.0" } }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "requires": { - "path-is-inside": "1.0.2" + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" } }, - "is-property": { + "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", "dev": true }, - "is-regex": { + "node_modules/is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, - "requires": { - "has": "1.0.1" + "dependencies": { + "has": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true, - "requires": { - "tryit": "1.0.3" - } + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true }, - "is-stream": { + "node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-symbol": { + "node_modules/is-symbol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "is-typedarray": { + "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, - "isarray": { + "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isemail": { + "node_modules/isemail": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.2.tgz", "integrity": "sha512-zfRhJn9rFSGhzU5tGZqepRSAj3+g6oTOHxMGGriWNJZzyLPUK8H7VHpqKntegnW8KLyGA9zwuNaCoopl40LTpg==", - "requires": { - "punycode": "2.1.1" + "dependencies": { + "punycode": "2.x.x" + }, + "engines": { + "node": ">=4.0.0" } }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isstream": { + "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "jmespath": { + "node_modules/jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", - "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "engines": { + "node": ">= 0.6.0" + } }, - "joi": { + "node_modules/joi": { "version": "13.4.0", "resolved": "https://registry.npmjs.org/joi/-/joi-13.4.0.tgz", "integrity": "sha512-JuK4GjEu6j7zr9FuVe2MAseZ6si/8/HaY0qMAejfDFHp7jcH4OKE937mIHM5VT4xDS0q7lpQbszbxKV9rm0yUg==", - "requires": { - "hoek": "5.0.3", - "isemail": "3.1.2", - "topo": "3.0.0" + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dependencies": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + }, + "engines": { + "node": ">=8.9.0" } }, - "js-cookie": { + "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" }, - "js-tokens": { + "node_modules/js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsbn": { + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, - "json-parse-better-errors": { + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema": { + "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, - "json-schema-traverse": { + "node_modules/json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "node_modules/json-stable-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", + "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", "dev": true, - "requires": { - "jsonify": "0.0.0" + "dependencies": { + "jsonify": "^0.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "json-stringify-safe": { + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "json5": { + "node_modules/json5": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", - "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=" + "integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=", + "bin": { + "json5": "lib/cli.js" + } }, - "jsonfile": { + "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "4.1.11" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "jsonwebtoken": { + "node_modules/jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "requires": { - "jws": "3.2.2", - "lodash.includes": "4.3.0", - "lodash.isboolean": "3.0.3", - "lodash.isinteger": "4.0.4", - "lodash.isnumber": "3.0.3", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.once": "4.1.1", - "ms": "2.1.3", - "semver": "5.7.1" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" } }, - "jsprim": { + "node_modules/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, - "jsx-ast-utils": { + "node_modules/jsx-ast-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", "dev": true, - "requires": { - "array-includes": "3.0.3" + "dependencies": { + "array-includes": "^3.0.3" + }, + "engines": { + "node": ">=4.0" } }, - "jwa": { + "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { + "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, - "jwks-rsa": { + "node_modules/jwks-rsa": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.12.3.tgz", "integrity": "sha512-cFipFDeYYaO9FhhYJcZWX/IyZgc0+g316rcHnDpT2dNRNIE/lMOmWKKqp09TkJoYlNFzrEVODsR4GgXJMgWhnA==", - "requires": { + "dependencies": { "@types/express-jwt": "0.0.42", - "axios": "0.21.1", - "debug": "4.3.1", - "http-proxy-agent": "4.0.1", - "https-proxy-agent": "5.0.0", - "jsonwebtoken": "8.5.1", - "limiter": "1.1.5", - "lru-memoizer": "2.1.4", - "ms": "2.1.3", - "proxy-from-env": "1.1.0" - }, - "dependencies": { - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4.3.1" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "1.14.0" - } - }, + "axios": "^0.21.1", + "debug": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "jsonwebtoken": "^8.5.1", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.2", + "ms": "^2.1.2", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/jwks-rsa/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/jwks-rsa/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/jwks-rsa/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/jwks-rsa/node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "follow-redirects": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", - "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==" - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1.1.2", - "agent-base": "6.0.2", - "debug": "4.3.1" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6.0.2", - "debug": "4.3.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "optional": true } } }, - "jws": { + "node_modules/jwks-rsa/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jws": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "1.4.1", - "safe-buffer": "5.1.1" + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" } }, - "jwt-decode": { + "node_modules/jwt-decode": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" }, - "le_node": { + "node_modules/le_node": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/le_node/-/le_node-1.8.0.tgz", "integrity": "sha512-NXzjxBskZ4QawTNwlGdRG05jYU0LhV2nxxmP3x7sRMHyROV0jPdyyikO9at+uYrWX3VFt0Y/am11oKITedx0iw==", - "requires": { + "dependencies": { "babel-runtime": "6.6.1", "codependency": "0.1.4", "json-stringify-safe": "5.0.1", @@ -2677,261 +4694,319 @@ "reconnect-core": "1.3.0", "semver": "5.1.0" }, - "dependencies": { - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "semver": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz", - "integrity": "sha1-hfLPhVBGXE3wAM99hvawVBBqueU=" - } + "engines": { + "iojs": ">=0.10", + "node": ">=0.8.0", + "npm": ">=1.4.6" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/le_node/node_modules/lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "node_modules/le_node/node_modules/semver": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz", + "integrity": "sha512-sfKXKhcz5XVyfUZa2V4RbjK0xjOJCMLNF9H4p4v0UCo9wNHM/lH9RDuyDbGEtxWLMDlPBc8xI7AbbVLKXty+rQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "limiter": { + "node_modules/limiter": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "linkify-it": { + "node_modules/linkify-it": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", "integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=", - "requires": { - "uc.micro": "1.0.5" + "dependencies": { + "uc.micro": "^1.0.1" } }, - "load-json-file": { + "node_modules/load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "locate-path": { + "node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, - "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" - }, "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" } }, - "lodash": { + "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash.clonedeep": { + "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, - "lodash.cond": { + "node_modules/lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", "dev": true }, - "lodash.includes": { + "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" }, - "lodash.isboolean": { + "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, - "lodash.isinteger": { + "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" }, - "lodash.isnumber": { + "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" }, - "lodash.isplainobject": { + "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" }, - "lodash.isstring": { + "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, - "lodash.once": { + "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, - "lodash.pick": { + "node_modules/lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true }, - "loose-envify": { + "node_modules/loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, - "requires": { - "js-tokens": "3.0.2" + "dependencies": { + "js-tokens": "^3.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "lru-cache": { + "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "4.0.0" + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "lru-memoizer": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", - "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", - "requires": { - "lodash.clonedeep": "4.5.0", - "lru-cache": "4.0.2" - }, - "dependencies": { - "lru-cache": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } + "node_modules/lru-memoizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", + "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "dependencies": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" } }, - "markdown-it": { + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, + "node_modules/markdown-it": { "version": "8.4.1", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.1.tgz", "integrity": "sha512-CzzqSSNkFRUf9vlWvhK1awpJreMRqdCrBvZ8DIoDWTOkESMIF741UPAhuAmbyWmdiFPA6WARNhnu2M6Nrhwa+A==", - "requires": { - "argparse": "1.0.9", - "entities": "1.1.1", - "linkify-it": "2.0.3", - "mdurl": "1.0.1", - "uc.micro": "1.0.5" + "dependencies": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" } }, - "mdurl": { + "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, - "media-typer": { + "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } }, - "merge-descriptors": { + "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, - "methods": { + "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } }, - "millisecond": { + "node_modules/millisecond": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/millisecond/-/millisecond-0.1.2.tgz", - "integrity": "sha1-bMWtOGJByrjniv+WT4cCjuyS2sU=" + "integrity": "sha512-BJ8XtxY+woL+5TkP6uS6XvOArm0JVrX2otkgtWZseHpIax0oOOPW3cnwhOjRqbEJg7YRO/BDF7fO/PTWNT3T9Q==" }, - "mime": { + "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } }, - "mime-db": { + "node_modules/mime-db": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.17", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", - "requires": { - "mime-db": "1.30.0" + "dependencies": { + "mime-db": "~1.30.0" + }, + "engines": { + "node": ">= 0.6" } }, - "min-document": { + "node_modules/min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", "dev": true, - "requires": { - "dom-walk": "0.1.1" + "dependencies": { + "dom-walk": "^0.1.0" } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.8" + "devOptional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "devOptional": true }, - "mkdirp": { + "node_modules/mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "devOptional": true, + "dependencies": { "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "mocha": { + "node_modules/mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "dev": true, - "requires": { + "dependencies": { "browser-stdout": "1.3.1", "commander": "2.15.1", "debug": "3.1.0", @@ -2944,1590 +5019,2215 @@ "mkdirp": "0.5.1", "supports-color": "5.4.0" }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, "dependencies": { - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "moment": { + "node_modules/moment": { "version": "2.22.2", "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "engines": { + "node": "*" + } }, - "ms": { + "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "murmur-hash-js": { + "node_modules/murmur-hash-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/murmur-hash-js/-/murmur-hash-js-1.0.0.tgz", "integrity": "sha1-UEEEkmnJZjPIZjhpYLL0KJ515bA=" }, - "mute-stream": { + "node_modules/mute-stream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg==", "dev": true }, - "mv": { + "node_modules/mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", "optional": true, - "requires": { - "mkdirp": "0.5.1", - "ncp": "2.0.0", - "rimraf": "2.4.5" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "optional": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "optional": true, - "requires": { - "glob": "6.0.4" - } - } + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "optional": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "optional": true, + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" } }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "node_modules/nan": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", "optional": true }, - "natural-compare": { + "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "ncp": { + "node_modules/ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "optional": true + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "optional": true, + "bin": { + "ncp": "bin/ncp" + } }, - "negotiator": { + "node_modules/negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } }, - "nerf-dart": { + "node_modules/nerf-dart": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=", "dev": true }, - "netrc": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/netrc/-/netrc-0.1.4.tgz", - "integrity": "sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=" + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true }, - "nice-simple-logger": { + "node_modules/nice-simple-logger": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nice-simple-logger/-/nice-simple-logger-1.0.1.tgz", "integrity": "sha1-D55khSe+e+PkmrdvqMjAmK+VG/Y=", - "requires": { - "lodash": "4.17.21" + "dependencies": { + "lodash": "^4.3.0" } }, - "nice-try": { + "node_modules/nice-try": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", "dev": true }, - "no-kafka": { + "node_modules/no-kafka": { "version": "3.2.10", "resolved": "https://registry.npmjs.org/no-kafka/-/no-kafka-3.2.10.tgz", "integrity": "sha1-0sq8QwZbSS24wVyiOK6V8WgIGvU=", - "requires": { + "dependencies": { "@types/bluebird": "3.5.0", - "@types/lodash": "4.14.110", - "bin-protocol": "3.0.4", - "bluebird": "3.5.1", - "buffer-crc32": "0.2.13", - "hashring": "3.2.0", - "lodash": "4.17.5", - "murmur-hash-js": "1.0.0", - "nice-simple-logger": "1.0.1", - "wrr-pool": "1.1.3" - }, - "dependencies": { - "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + "@types/lodash": "^4.14.55", + "bin-protocol": "^3.0.4", + "bluebird": "^3.3.3", + "buffer-crc32": "^0.2.5", + "hashring": "^3.2.0", + "lodash": "=4.17.5", + "murmur-hash-js": "^1.0.0", + "nice-simple-logger": "^1.0.1", + "wrr-pool": "^1.0.3" + } + }, + "node_modules/no-kafka/node_modules/lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "node_modules/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true } } }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true - }, - "node-gitlab-api": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/node-gitlab-api/-/node-gitlab-api-2.2.8.tgz", - "integrity": "sha512-wc/2/rnfB1O/3aCz0E6LoFY83KkfAsjvHYFQCAf+OEtRwxmDxEMFKihW9VNL6hHWNDFsV+QE16KkpimdKgngOQ==", - "requires": { - "@babel/runtime": "7.0.0-beta.51", - "humps": "2.0.1", - "lodash.pick": "4.4.0", - "parse-link-header": "1.0.1", - "request": "2.87.0", - "request-promise": "4.2.2", - "url-join": "4.0.0" - } - }, - "nodemailer": { + "node_modules/nodemailer": { "version": "4.6.7", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.6.7.tgz", - "integrity": "sha512-GIAAYvs9XIP1fBa8wR89ukUh3yjL44pom5LKY5nTZcL+Zp9sRkqL8wgskyBQECQg9CPsDX/fjTZx8MNz20t0jA==" + "integrity": "sha512-GIAAYvs9XIP1fBa8wR89ukUh3yjL44pom5LKY5nTZcL+Zp9sRkqL8wgskyBQECQg9CPsDX/fjTZx8MNz20t0jA==", + "engines": { + "node": ">=6.0.0" + } }, - "normalize-package-data": { + "node_modules/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.3.0", - "validate-npm-package-license": "3.0.1" + "dependencies": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "normalize-url": { + "node_modules/normalize-url": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.2.0.tgz", "integrity": "sha512-WvF3Myk0NhXkG8S9bygFM4IC1KOvnVJGq0QoGeoqOYOBeinBZp5ybW3QuYbTc89lkWBMM9ZBO4QGRoc0353kKA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "npm-run-path": { + "node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, - "requires": { - "path-key": "2.0.1" + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "number-is-nan": { + "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "oauth-sign": { + "node_modules/oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true, + "engines": { + "node": "*" + } }, - "object-assign": { + "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "object-keys": { + "node_modules/object-keys": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "object-path": { + "node_modules/object-path": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=", + "engines": { + "node": ">=0.10.0" + } }, - "object.getownpropertydescriptors": { + "node_modules/object.getownpropertydescriptors": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.12.0" + "dependencies": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + }, + "engines": { + "node": ">= 0.8" } }, - "on-finished": { + "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { + "dependencies": { "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" + "dependencies": { + "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true + "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "os-homedir": { + "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "engines": { + "node": ">=0.10.0" + } }, - "p-finally": { + "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-limit": { + "node_modules/p-limit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-locate": { + "node_modules/p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, - "requires": { - "p-limit": "1.1.0" + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-headers": { + "node_modules/parse-headers": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", "dev": true, - "requires": { - "for-each": "0.3.3", + "dependencies": { + "for-each": "^0.3.2", "trim": "0.0.1" } }, - "parse-json": { + "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, - "requires": { - "error-ex": "1.3.1" + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "parse-link-header": { + "node_modules/parse-link-header": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz", "integrity": "sha1-vt/g0hGK64S+deewJUGeyKYRQKc=", - "requires": { - "xtend": "4.0.1" + "dev": true, + "dependencies": { + "xtend": "~4.0.1" } }, - "parseurl": { + "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } }, - "path-exists": { + "node_modules/path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, - "requires": { - "pinkie-promise": "2.0.1" + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-is-inside": { + "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, - "path-key": { + "node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, - "path-to-regexp": { + "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, - "path-type": { + "node_modules/path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, - "requires": { - "pify": "2.3.0" + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "pathval": { + "node_modules/pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "performance-now": { + "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "pify": { + "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pinkie": { + "node_modules/pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pinkie-promise": { + "node_modules/pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, - "requires": { - "pinkie": "2.0.4" + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, - "requires": { - "find-up": "1.1.2" + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pluralize": { + "node_modules/pluralize": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "integrity": "sha512-TH+BeeL6Ct98C7as35JbZLf8lgsRzlNJb5gklRIGHKaPkGl1esOKBc5ALUMd+q08Sr6tiEKM+Icbsxg5vuhMKQ==", "dev": true }, - "precond": { + "node_modules/precond": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "engines": { + "node": ">= 0.6" + } }, - "prettier": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.2.tgz", - "integrity": "sha512-McHPg0n1pIke+A/4VcaS2en+pTNjy4xF+Uuq86u/5dyDO59/TtFZtQ708QIRkEZ3qwKz3GVkVa6mpxK/CpB8Rg==", - "dev": true + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "process": { + "node_modules/process": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.6.0" + } }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "progress": { + "node_modules/progress": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true + "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "prop-types": { + "node_modules/prop-types": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "dev": true, - "requires": { - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "dependencies": { + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, - "protocol-buffers-schema": { + "node_modules/protocol-buffers-schema": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz", "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w==" }, - "proxy-addr": { + "node_modules/proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "requires": { - "forwarded": "0.1.2", + "dependencies": { + "forwarded": "~0.1.2", "ipaddr.js": "1.9.0" + }, + "engines": { + "node": ">= 0.10" } }, - "proxy-from-env": { + "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "pseudomap": { + "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, - "punycode": { + "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } }, - "q": { + "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } }, - "qs": { + "node_modules/qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "engines": { + "node": ">=0.6" + } }, - "querystring": { + "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "range-parser": { + "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } }, - "raw-body": { + "node_modules/raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { + "dependencies": { "bytes": "3.1.0", "http-errors": "1.7.2", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "rc": { + "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, - "requires": { - "deep-extend": "0.6.0", - "ini": "1.3.7", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" } }, - "read-pkg": { + "node_modules/rc/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "read-pkg-up": { + "node_modules/read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - } + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "readline2": { + "node_modules/readline2": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==", "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", "mute-stream": "0.0.5" } }, - "rechoir": { + "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dev": true, - "requires": { - "resolve": "1.4.0" + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" } }, - "reconnect-core": { + "node_modules/reconnect-core": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/reconnect-core/-/reconnect-core-1.3.0.tgz", - "integrity": "sha1-+65SkZp4d9hE4yRtAaLyZwHIM8g=", - "requires": { - "backoff": "2.5.0" + "integrity": "sha512-+gLKwmyRf2tjl6bLR03DoeWELzyN6LW9Xgr3vh7NXHHwPi0JC0N2TwPyf90oUEBkCRcD+bgQ+s3HORoG3nwHDg==", + "dependencies": { + "backoff": "~2.5.0" } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "registry-auth-token": { + "node_modules/registry-auth-token": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", "dev": true, - "requires": { - "rc": "1.2.8", - "safe-buffer": "5.1.1" + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" } }, - "request": { + "node_modules/request": { "version": "2.87.0", "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.7.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + }, + "engines": { + "node": ">= 4" } }, - "request-promise": { + "node_modules/request-promise": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", - "requires": { - "bluebird": "3.5.1", + "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "bluebird": "^3.5.0", "request-promise-core": "1.1.1", - "stealthy-require": "1.1.1", - "tough-cookie": "2.3.4" + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "request-promise-core": { + "node_modules/request-promise-core": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", - "requires": { - "lodash": "4.17.21" + "dev": true, + "dependencies": { + "lodash": "^4.13.1" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "require-uncached": { + "node_modules/require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", + "dev": true, + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached/node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", "dev": true, - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "engines": { + "node": ">=0.10.0" } }, - "resolve": { + "node_modules/resolve": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", "dev": true, - "requires": { - "path-parse": "1.0.5" + "dependencies": { + "path-parse": "^1.0.5" } }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "restore-cursor": { + "node_modules/restore-cursor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", + "dev": true, + "dependencies": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "requires": { - "glob": "7.1.2" + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "run-async": { + "node_modules/run-async": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==", "dev": true, - "requires": { - "once": "1.4.0" + "dependencies": { + "once": "^1.3.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "rx-lite": { + "node_modules/rx-lite": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ==", "dev": true }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, - "safe-json-stringify": { + "node_modules/safe-json-stringify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", "optional": true }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sax": { + "node_modules/sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, - "semver": { + "node_modules/semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true + "dev": true, + "bin": { + "semver": "bin/semver" + } }, - "send": { + "node_modules/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { + "dependencies": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.7.2", + "http-errors": "~1.7.2", "mime": "1.6.0", "ms": "2.1.1", - "on-finished": "2.3.0", - "range-parser": "1.2.1", - "statuses": "1.5.0" + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" } }, - "serve-static": { + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.3", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "setprototypeof": { + "node_modules/setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "shebang-command": { + "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "requires": { - "shebang-regex": "1.0.0" + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "shelljs": { + "node_modules/shelljs": { "version": "0.7.8", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "integrity": "sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==", "dev": true, - "requires": { - "glob": "7.1.2", - "interpret": "1.0.4", - "rechoir": "0.6.2" + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "iojs": "*", + "node": ">=0.11.0" } }, - "side-channel": { + "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "1.0.2", - "get-intrinsic": "1.1.1", - "object-inspect": "1.10.2" + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "simple-lru-cache": { + "node_modules/simple-lru-cache": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/simple-lru-cache/-/simple-lru-cache-0.0.2.tgz", "integrity": "sha1-1ZzDoZPBpdAyD4Tucy9uRxPlEd0=" }, - "slice-ansi": { + "node_modules/slice-ansi": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "integrity": "sha512-up04hB2hR92PgjpyU3y/eg91yIBILyjVY26NvvciY3EVVPjybkMszMpXQ9QAkcS3I5rtJBDLoTxxg+qvW8c7rw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" + "dependencies": { + "spdx-license-ids": "^1.0.2" } }, - "spdx-expression-parse": { + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", "dev": true }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", "dev": true }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, - "sshpk": { + "node_modules/sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "dashdash": "^1.12.0", + "getpass": "^0.1.1", + "safer-buffer": "^2.0.2" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + }, + "optionalDependencies": { + "bcrypt-pbkdf": "^1.0.0", + "ecc-jsbn": "~0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" } }, - "stack-trace": { + "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } }, - "statuses": { + "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } }, - "stealthy-require": { + "node_modules/stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "safe-buffer": "5.1.1" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "string-width": { + "node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "strip-ansi": { + "node_modules/string-width/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "ansi-regex": "2.1.1" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { + "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "strip-eof": { + "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "superagent": { + "node_modules/superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", - "requires": { - "component-emitter": "1.2.1", - "cookiejar": "2.1.2", - "debug": "3.1.0", - "extend": "3.0.2", - "form-data": "2.3.1", - "formidable": "1.2.2", - "methods": "1.1.2", - "mime": "1.6.0", - "qs": "6.5.1", - "readable-stream": "2.3.7" - }, + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", "dependencies": { - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.1", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "5.1.1" - } - } + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" } }, - "superagent-promise": { + "node_modules/superagent-promise": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/superagent-promise/-/superagent-promise-1.1.0.tgz", "integrity": "sha1-uvIti73UOamwfdEPjAj1T+JQNTM=" }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "node_modules/superagent/node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/superagent/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/superagent/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "table": { + "node_modules/table": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "integrity": "sha512-RZuzIOtzFbprLCE0AXhkI0Xi42ZJLZhCC+qkwuMLf/Vjz3maWpA8gz1qMdbmNoI9cOROT2Am/DxeRyXenrL11g==", "dev": true, - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.21", + "dependencies": { + "ajv": "^4.7.0", + "ajv-keywords": "^1.0.0", + "chalk": "^1.1.1", + "lodash": "^4.0.0", "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - } + "string-width": "^2.0.0" } }, - "tc-core-library-js": { - "version": "github:appirio-tech/tc-core-library-js#f45352974dafe5a10c86fc50bdd59ef399b50c65", - "requires": { - "auth0-js": "9.16.0", - "axios": "0.19.0", - "bunyan": "1.8.15", - "jsonwebtoken": "8.5.1", - "jwks-rsa": "1.12.3", - "le_node": "1.8.0", - "lodash": "4.17.21", - "millisecond": "0.1.2", - "request": "2.88.2" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "3.1.3", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.4.1" - } - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "1.0.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.8", - "mime-types": "2.1.32" - } - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "6.12.6", - "har-schema": "2.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" - }, - "mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", - "requires": { - "mime-db": "1.49.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.11.0", - "caseless": "0.12.0", - "combined-stream": "1.0.8", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.3", - "har-validator": "5.1.5", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.32", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.2.1", - "tough-cookie": "2.5.0", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" - } + "node_modules/table/node_modules/ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha512-I/bSHSNEcFFqXLf91nchoNB9D1Kie3QKcWdchYUaoIg1+1bdWDkdfdlvdIOJbi9U8xR0y+MWc5D+won9v95WlQ==", + "dev": true, + "dependencies": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tc-core-library-js": { + "version": "2.4.1", + "resolved": "git+ssh://git@github.com/appirio-tech/tc-core-library-js.git#f45352974dafe5a10c86fc50bdd59ef399b50c65", + "integrity": "sha512-vgg0A0VFHZhMGyffPOeGTk2YUkyqNQF2aE9jY9MhbYzszYDfxFu1SKzF4p0TBXtAW27c+EqsKcIci+NU5ASPdA==", + "license": "ISC", + "dependencies": { + "auth0-js": "^9.4.2", + "axios": "^0.19.0", + "bunyan": "^1.8.12", + "jsonwebtoken": "^8.3.0", + "jwks-rsa": "^1.3.0", + "le_node": "^1.3.1", + "lodash": "^4.17.10", + "millisecond": "^0.1.2", + "request": "^2.88.0" + }, + "engines": { + "node": ">= 5" + } + }, + "node_modules/tc-core-library-js/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/tc-core-library-js/node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/tc-core-library-js/node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/tc-core-library-js/node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/tc-core-library-js/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/tc-core-library-js/node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tc-core-library-js/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/tc-core-library-js/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/tc-core-library-js/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/tc-core-library-js/node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/tc-core-library-js/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tc-core-library-js/node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tc-core-library-js/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "1.8.0", - "punycode": "2.1.1" - } + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/tc-core-library-js/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "toidentifier": { + "node_modules/toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } }, - "topcoder-healthcheck-dropin": { + "node_modules/topcoder-healthcheck-dropin": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/topcoder-healthcheck-dropin/-/topcoder-healthcheck-dropin-1.0.3.tgz", "integrity": "sha512-k8X84IC2NALu1v8cD3SZXY0MMZAMWw2uzHmjXDlgXwpS5xnXdwnVU+BpJWqg1uz1OuYDdeaAIPguqnhs7G6Y0A==", - "requires": { - "express": "4.17.1" + "dependencies": { + "express": "^4.16.3" } }, - "topo": { + "node_modules/topo": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz", "integrity": "sha512-Tlu1fGlR90iCdIPURqPiufqAlCZYzLjHYVVbcFWDMcX7+tK8hdZWAfsMrD/pBul9jqHHwFjNdf1WaxA9vTRRhw==", - "requires": { - "hoek": "5.0.3" + "deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).", + "dependencies": { + "hoek": "5.x.x" + }, + "engines": { + "node": ">=8.0.0" } }, - "tough-cookie": { + "node_modules/tough-cookie": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "requires": { - "punycode": "1.4.1" - }, + "dev": true, "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" } }, - "trim": { + "node_modules/tough-cookie/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "deprecated": "Use String.prototype.trim() instead", "dev": true }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true - }, - "tunnel-agent": { + "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "5.1.1" + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" } }, - "tweetnacl": { + "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "optional": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { - "prelude-ls": "1.1.2" + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "type-is": { + "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { + "dependencies": { "media-typer": "0.3.0", - "mime-types": "2.1.24" + "mime-types": "~2.1.24" }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", "dependencies": { - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - } + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "uc.micro": { + "node_modules/uc.micro": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz", "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==" }, - "unfetch": { + "node_modules/unfetch": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" }, - "universalify": { + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "2.1.1" + "dependencies": { + "punycode": "^2.1.0" } }, - "url": { + "node_modules/url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { + "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } } }, - "url-join": { + "node_modules/url-join": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", - "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=" - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=", "dev": true }, - "user-home": { + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "node_modules/user-home": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==", "dev": true, - "requires": { - "os-homedir": "1.0.2" + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "util": { + "node_modules/util": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/util/-/util-0.11.0.tgz", "integrity": "sha512-5n12uMzKCjvB2HPFHnbQSjaqAa98L5iIXmHrZCLavuZVe0qe/SJGbDGWlpaHk5lnBkWRDO+dRu1/PgmUYKPPTw==", - "requires": { + "dependencies": { "inherits": "2.0.3" } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "util.promisify": { + "node_modules/util.promisify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", "dev": true, - "requires": { - "define-properties": "1.1.2", - "object.getownpropertydescriptors": "2.0.3" + "dependencies": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" } }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } }, - "uuid": { + "node_modules/uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "dependencies": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" } }, - "validator": { + "node_modules/validator": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.0.0.tgz", - "integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA==" + "integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA==", + "engines": { + "node": ">= 0.10" + } }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } }, - "verror": { + "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "1.0.0", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "which": { + "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "requires": { - "isexe": "2.0.0" + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "winchan": { + "node_modules/winchan": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/winchan/-/winchan-0.2.2.tgz", "integrity": "sha512-pvN+IFAbRP74n/6mc6phNyCH8oVkzXsto4KCHPJ2AScniAnA1AmeLI03I2BzjePpaClGSI4GUMowzsD3qz5PRQ==" }, - "winston": { + "node_modules/winston": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.3.tgz", "integrity": "sha512-GYKuysPz2pxYAVJD2NPsDLP5Z79SDEzPm9/j4tCjkF/n89iBNGBMJcR+dMUqxgPNgoSs6fVygPi+Vl2oxIpBuw==", - "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "stack-trace": "0.0.10" - }, - "dependencies": { - "async": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" - } + "dependencies": { + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.10.0" } }, - "wordwrap": { + "node_modules/winston/node_modules/async": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "write": { + "node_modules/write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", "dev": true, - "requires": { - "mkdirp": "0.5.1" + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "wrr-pool": { + "node_modules/wrr-pool": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wrr-pool/-/wrr-pool-1.1.3.tgz", "integrity": "sha1-/a0i8uofMDY//l14HPeUl6d/8H4=", - "requires": { - "lodash": "4.17.21" + "dependencies": { + "lodash": "^4.0.1" } }, - "xhr": { + "node_modules/xcase": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xcase/-/xcase-2.0.1.tgz", + "integrity": "sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw==" + }, + "node_modules/xhr": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", "dev": true, - "requires": { - "global": "4.3.2", - "is-function": "1.0.1", - "parse-headers": "2.0.1", - "xtend": "4.0.1" + "dependencies": { + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" } }, - "xml2js": { + "node_modules/xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "requires": { - "sax": "1.2.1", - "xmlbuilder": "9.0.7" + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" } }, - "xmlbuilder": { + "node_modules/xmlbuilder": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "engines": { + "node": ">=4.0" + } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true, + "engines": { + "node": ">=0.4" + } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index d7e5644..974ad42 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ }, "homepage": "https://gitlab.com/luettich/processor#README", "dependencies": { + "@gitbeaker/rest": "^39.12.0", "@octokit/rest": "^18.9.0", "axios": "^0.19.0", "circular-json": "^0.5.7", @@ -40,7 +41,6 @@ "markdown-it": "^8.4.1", "moment": "^2.22.2", "no-kafka": "^3.2.10", - "node-gitlab-api": "^2.2.8", "nodemailer": "^4.6.7", "superagent": "^3.6.0", "superagent-promise": "^1.1.0", @@ -52,9 +52,11 @@ }, "devDependencies": { "chai": "^4.1.2", + "eslint": "^8.47.0", "eslint-config-topcoder": "^2.0.0", "eslint-plugin-babel": "^4.1.2", "eslint-plugin-chai-expect": "^1.1.1", + "eslint-plugin-jsdoc": "^46.5.0", "eslint-plugin-react": "^7.10.0", "gitlab": "^3.7.0", "mocha": "^5.2.0", diff --git a/services/GitlabService.js b/services/GitlabService.js index 9e100f3..6d24fd4 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -12,14 +12,14 @@ const config = require('config'); const _ = require('lodash'); const Joi = require('joi'); -const GitlabAPI = require('node-gitlab-api'); +const {Gitlab} = require('@gitbeaker/rest'); +const superagent = require('superagent'); +const superagentPromise = require('superagent-promise'); const logger = require('../utils/logger'); const errors = require('../utils/errors'); const models = require('../models'); const helper = require('../utils/helper'); const dbHelper = require('../utils/db-helper'); -const superagent = require('superagent'); -const superagentPromise = require('superagent-promise'); const request = superagentPromise(superagent, Promise); // milliseconds per second @@ -36,13 +36,12 @@ const copilotUserSchema = Joi.object().keys({ /** * authenticate the gitlab using access token * @param {String} accessToken the access token of copilot - * @returns {Object} the gitlab instance * @private */ async function _authenticate(accessToken) { try { - const gitlab = GitlabAPI({ - url: config.GITLAB_API_BASE_URL, + const gitlab = new Gitlab({ + host: config.GITLAB_API_BASE_URL, oauthToken: accessToken }); return gitlab; @@ -53,7 +52,7 @@ async function _authenticate(accessToken) { /** * Removes assignees from issue - * @param {Object} gitlab the gitlab instance + * @param {import('@gitbeaker/core').Gitlab} gitlab the gitlab instance * @param {Number} projectId the project id * @param {Number} issueId the issue number * @param {Array} assignees the users to remove @@ -61,9 +60,9 @@ async function _authenticate(accessToken) { */ async function _removeAssignees(gitlab, projectId, issueId, assignees) { try { - const issue = await gitlab.projects.issues.show(projectId, issueId); + const issue = await gitlab.Issues.show(issueId, {projectId}); const oldAssignees = _.difference(issue.assignee_ids, assignees); - await gitlab.projects.issues.edit(projectId, issueId, {assignee_ids: oldAssignees}); + await gitlab.Issues.edit(projectId, issueId, {assigneeIds: oldAssignees}); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during remove assignees from issue.'); } @@ -94,7 +93,7 @@ async function createComment(copilot, project, issueId, body) { const gitlab = await _authenticate(refreshedCopilot.accessToken); try { body = helper.prepareAutomatedComment(body, copilot); - await gitlab.projects.issues.notes.create(projectId, issueId, {body}); + await gitlab.IssueNotes.create(projectId, issueId, body); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during creating comment on issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); } @@ -121,7 +120,7 @@ async function updateIssue(copilot, project, issueId, title) { const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); try { - await gitlab.projects.issues.edit(projectId, issueId, {title}); + await gitlab.Issues.edit(projectId, issueId, {title}); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during updating issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); } @@ -148,12 +147,12 @@ async function assignUser(copilot, project, issueId, userId) { const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); try { - const issue = await gitlab.projects.issues.show(projectId, issueId); - const oldAssignees = _.without(issue.assignee_ids, userId); + const issue = await gitlab.Issues.show(issueId, {projectId}); + const oldAssignees = _.without(issue.assignees.map((a) => a.id), userId); if (oldAssignees && oldAssignees.length > 0) { await _removeAssignees(gitlab, projectId, issueId, oldAssignees); } - await gitlab.projects.issues.edit(projectId, issueId, {assignee_ids: [userId]}); + await gitlab.Issues.edit(projectId, issueId, {assigneeIds: [userId]}); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during assigning issue user.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); } @@ -195,7 +194,7 @@ async function getUsernameById(copilot, userId) { Joi.attempt({copilot, userId}, getUsernameById.schema); const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); - const user = await gitlab.users.show(userId); + const user = await gitlab.Users.show(userId); return user ? user.username : null; } @@ -214,7 +213,7 @@ async function getUserIdByLogin(copilot, login) { Joi.attempt({copilot, login}, getUserIdByLogin.schema); const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); - const user = await gitlab.users.all({username: login}); + const user = await gitlab.Users.all({username: login}); return user.length ? user[0].id : null; } @@ -241,7 +240,7 @@ async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLa const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL) .push(config.FIX_ACCEPTED_ISSUE_LABEL, config.PAID_ISSUE_LABEL).value(); try { - await gitlab.projects.issues.edit(projectId, issueId, {labels: labels.join(',')}); + await gitlab.Issues.edit(projectId, issueId, {labels}); let commentMessage = ''; commentMessage += `Payment task has been updated: ${config.TC_URL}/challenges/${challengeUUID}\n\n`; @@ -253,7 +252,7 @@ async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLa commentMessage += `Challenge \`${challengeUUID}\` has been paid and closed.`; const body = helper.prepareAutomatedComment(commentMessage, copilot); - await gitlab.projects.issues.notes.create(projectId, issueId, {body}); + await gitlab.IssueNotes.create(projectId, issueId, body); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during updating issue as paid.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); } @@ -283,7 +282,7 @@ async function changeState(copilot, project, issueId, state) { const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); try { - await gitlab.projects.issues.edit(projectId, issueId, {state_event: state}); + await gitlab.Issues.edit(projectId, issueId, {stateEvent: state}); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during updating status of issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); } @@ -310,7 +309,7 @@ async function addLabels(copilot, project, issueId, labels) { const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); try { - await gitlab.projects.issues.edit(projectId, issueId, {labels: _.join(labels, ',')}); + await gitlab.Issues.edit(projectId, issueId, {labels: _.join(labels, ',')}); } catch (err) { throw errors.handleGitLabError(err, 'Error occurred during adding label in issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); } @@ -324,6 +323,49 @@ addLabels.schema = { labels: Joi.array().items(Joi.string()).required() }; +/** + * Get gitlab repository + * @param {Object} user The user + * @param {Object} repoURL The repository URL + */ +async function getRepository(user, repoURL) { + const refreshedUser = await _refreshGitlabUserAccessToken(user); + const gitlab = await _authenticate(refreshedUser.accessToken); + const _repoURL = repoURL.replace(`${config.GITLAB_API_BASE_URL}/`, ''); + return await gitlab.Projects.show(_repoURL); +} + +/** + * Add a user to a gitlab repository + * @param {Object} copilot The copilot + * @param {import('@gitbeaker/rest').ProjectSchema} repository The repository + * @param {Object} user The user + * @param {import('@gitbeaker/rest').AccessLevel} accessLevel The user role + */ +async function addUserToRepository(copilot, repository, user, accessLevel) { + const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); + const gitlab = await _authenticate(refreshedCopilot.accessToken); + const member = await gitlab.ProjectMembers.show(repository.id, user.userProviderId); + if (!member) { + await gitlab.ProjectMembers.add(repository.id, user.userProviderId, accessLevel); + return; + } + if (member.access_level !== accessLevel) { + await gitlab.ProjectMembers.edit(repository.id, user.userProviderId, accessLevel); + } +} + +/** + * Fork a gitlab repository + * @param {Object} user The user + * @param {ProjectSchema} repository The repository + */ +async function forkRepository(user, repository) { + const refreshedUser = await _refreshGitlabUserAccessToken(user); + const gitlab = await _authenticate(refreshedUser.accessToken); + await gitlab.Projects.fork(repository.id); +} + /** * Refresh the copilot access token if token is needed * @param {Object} copilot the copilot @@ -363,7 +405,10 @@ module.exports = { getUserIdByLogin, markIssueAsPaid, changeState, - addLabels + addLabels, + getRepository, + addUserToRepository, + forkRepository }; logger.buildService(module.exports); diff --git a/services/PrivateForkService.js b/services/PrivateForkService.js new file mode 100644 index 0000000..00e481c --- /dev/null +++ b/services/PrivateForkService.js @@ -0,0 +1,126 @@ +/* eslint-disable no-magic-numbers */ +/* + * Copyright (c) 2018 TopCoder, Inc. All rights reserved. + */ +'use strict'; + +/** + * This service will provide project operations. + * + * @author TCSCODER + * @version 1.0 + */ +const Joi = require('joi'); +const models = require('../models'); +const dbHelper = require('../utils/db-helper'); +const logger = require('../utils/logger'); +const GitlabService = require('../services/GitlabService'); +const {GITLAB_ACCESS_LEVELS} = require('../constants'); + +const ProjectChallengeMapping = models.ProjectChallengeMapping; +const Project = models.Project; +const Repository = models.Repository; +const User = models.User; +const GitlabUserMapping = models.GitlabUserMapping; + +/** + * Handles a user registration event. + * @param {Object} payload The event payload. + * @param {String} payload.challengeId The user handle. + * @param {String} payload.memberId The user email. + * @param {String} payload.memberHandle The user first name. + */ +async function process(payload) { + const {challengeId, memberId, memberHandle} = payload; + const logPrefix = `[PrivateForkService#handleUserRegistration (challengeId: ${challengeId}, memberId: ${memberId}, memberHandle: ${memberHandle})]: `; + // Check if there are projects mapped to the challenge + const filterValues = {}; + const filter = { + FilterExpression: '#challengeId = :challengeId', + ExpressionAttributeNames: { + '#challengeId': 'challengeId' + }, + ExpressionAttributeValues: { + ':challengeId': challengeId + } + }; + const projectChallengeMapping = await dbHelper.scan(ProjectChallengeMapping, filter, filterValues); + if (projectChallengeMapping.length === 0) { + logger.info(`${logPrefix}ProjectChallengeMapping not found for challengeId: ${challengeId}`); + return; + } + logger.debug(`${logPrefix}ProjectChallengeMapping: ${JSON.stringify(projectChallengeMapping)}`); + // Get Project + const projectId = projectChallengeMapping[0].projectId; + const project = await dbHelper.getById(Project, projectId); + if (!project) { + logger.info(`${logPrefix}Project not found for projectId: ${projectId}`); + return; + } + logger.debug(`${logPrefix}Project: ${JSON.stringify(project)}`); + // Get Repositories + const repositories = await dbHelper.queryAllRepositoriesByProjectId(Repository, project.id); + console.log(repositories); + if (!repositories || repositories.length === 0) { + logger.info(`${logPrefix}Repository not found for projectId: ${project.id}`); + return; + } + logger.debug(`${logPrefix}Repository: ${JSON.stringify(repositories)}`); + // Get Co-pilot GitlabUserMapping + const copilotGitlabUserMapping = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, project.copilot); + if (!copilotGitlabUserMapping) { + logger.info(`${logPrefix}GitlabUserMapping not found for copilot: ${project.copilot}`); + return; + } + logger.debug(`${logPrefix}GitlabUserMapping[Copilot]: ${JSON.stringify(copilotGitlabUserMapping)}`); + // Get Gitlab User + const copilotGitlabUser = await dbHelper.queryOneUserByType(User, copilotGitlabUserMapping.gitlabUsername, 'gitlab'); + if (!copilotGitlabUser) { + logger.info(`${logPrefix}GitlabUser not found for copilot: ${project.copilot}`); + return; + } + logger.debug(`${logPrefix}GitlabUser[Copilot]: ${JSON.stringify(copilotGitlabUser)}`); + // Get Member GitlabUserMapping + const memberGitlabUserMapping = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, memberHandle); + if (!memberGitlabUserMapping) { + logger.info(`${logPrefix}GitlabUserMapping not found for memberHandle: ${memberHandle}`); + return; + } + logger.debug(`${logPrefix}GitlabUserMapping[Member]: ${JSON.stringify(memberGitlabUserMapping)}`); + // Get Gitlab User + const memberGitlabUser = await dbHelper.queryOneUserByType(User, memberGitlabUserMapping.gitlabUsername, 'gitlab'); + if (!memberGitlabUser) { + logger.info(`${logPrefix}GitlabUser not found for memberHandle: ${memberHandle}`); + return; + } + logger.debug(`${logPrefix}GitlabUser[Member]: ${JSON.stringify(memberGitlabUser)}`); + await Promise.all(repositories.map(async (repo) => { + try { + const repository = await GitlabService.getRepository(copilotGitlabUser, repo.url); + if (!repository) { + logger.info(`${logPrefix}Repository not found for repo: ${repo}`); + return; + } + // Add user as a guest to the repo + await GitlabService.addUserToRepository(copilotGitlabUser, repository, memberGitlabUser, GITLAB_ACCESS_LEVELS.DEVELOPER); + // Fork the repository + await GitlabService.forkRepository(memberGitlabUser, repository); + } catch (err) { + logger.error(`${logPrefix}Error: ${err.message}`, err); + } + })); +} +process.schema = Joi.object().keys({ + payload: Joi.object().keys({ + challengeId: Joi.string().required(), + memberId: Joi.string().required(), + memberHandle: Joi.string().required() + }).required() +}); + +module.exports = { + process +}; + +logger.buildService(module.exports); + diff --git a/utils/db-helper.js b/utils/db-helper.js index 29cc2e4..37fb949 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -58,19 +58,19 @@ async function scan(model, scanParams) { async function queryOneIssue(model, repositoryId, number, provider) { return await new Promise((resolve, reject) => { model.query('repositoryId').eq(repositoryId) - .where('number') - .eq(number) - .filter('provider') - .eq(provider) - .all() - .exec((err, result) => { - if (err || !result) { - logger.debug(`queryOne. Error. ${err}`); - return reject(err); - } + .where('number') + .eq(number) + .filter('provider') + .eq(provider) + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOne. Error. ${err}`); + return reject(err); + } - return resolve(result.count === 0 ? null : result[0]); - }); + return resolve(result.count === 0 ? null : result[0]); + }); }); } @@ -87,13 +87,13 @@ async function queryOneActiveProject(model, repoUrl) { resolve(null); } else { model.queryOne('id').eq(repo.projectId).consistent() - .exec((err, result) => { - if (err) { - logger.debug(`queryOneActiveProject. Error. ${err}`); - return reject(err); - } - return resolve(result); - }); + .exec((err, result) => { + if (err) { + logger.debug(`queryOneActiveProject. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); } }); }); @@ -109,16 +109,16 @@ async function queryOneActiveProject(model, repoUrl) { async function queryOneUserByType(model, username, type) { return await new Promise((resolve, reject) => { model.query('username').eq(username) - .where('type') - .eq(type) - .all() - .exec((err, result) => { - if (err || !result) { - logger.debug(`queryOneUserByType. Error. ${err}`); - return reject(err); - } - return resolve(result.count === 0 ? null : result[0]); - }); + .where('type') + .eq(type) + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOneUserByType. Error. ${err}`); + return reject(err); + } + return resolve(result.count === 0 ? null : result[0]); + }); }); } @@ -131,14 +131,14 @@ async function queryOneUserByType(model, username, type) { async function queryOneUserMappingByTCUsername(model, tcusername) { return await new Promise((resolve, reject) => { model.queryOne('topcoderUsername').eq(tcusername) - .all() - .exec((err, result) => { - if (err) { - logger.debug(`queryOneUserMappingByTCUsername. Error. ${err}`); - return reject(err); - } - return resolve(result); - }); + .all() + .exec((err, result) => { + if (err) { + logger.debug(`queryOneUserMappingByTCUsername. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); }); } @@ -151,14 +151,14 @@ async function queryOneUserMappingByTCUsername(model, tcusername) { async function queryOneUserMappingByGithubUsername(model, username) { return await new Promise((resolve, reject) => { model.queryOne('githubUsername').eq(username) - .all() - .exec((err, result) => { - if (err || !result) { - logger.debug(`queryOneUserMappingByGithubUsername. Error. ${err}`); - return reject(err); - } - return resolve(result); - }); + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOneUserMappingByGithubUsername. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); }); } @@ -171,14 +171,14 @@ async function queryOneUserMappingByGithubUsername(model, username) { async function queryOneUserMappingByGitlabUsername(model, username) { return await new Promise((resolve, reject) => { model.queryOne('gitlabUsername').eq(username) - .all() - .exec((err, result) => { - if (err || !result) { - logger.debug(`queryOneUserMappingByGitlabUsername. Error. ${err}`); - return reject(err); - } - return resolve(result); - }); + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOneUserMappingByGitlabUsername. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); }); } @@ -191,14 +191,14 @@ async function queryOneUserMappingByGitlabUsername(model, username) { async function queryOneUserMappingByGithubUserId(model, userId) { return await new Promise((resolve, reject) => { model.queryOne('githubUserId').eq(userId) - .all() - .exec((err, result) => { - if (err || !result) { - logger.debug(`queryOneUserMappingByGithubUserId. Error. ${err}`); - return reject(err); - } - return resolve(result); - }); + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOneUserMappingByGithubUserId. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); }); } @@ -211,14 +211,34 @@ async function queryOneUserMappingByGithubUserId(model, userId) { async function queryOneUserMappingByGitlabUserId(model, userId) { return await new Promise((resolve, reject) => { model.queryOne('gitlabUserId').eq(userId) - .all() - .exec((err, result) => { - if (err || !result) { - logger.debug(`queryOneUserMappingByGitlabUserId. Error. ${err}`); - return reject(err); - } - return resolve(result); - }); + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOneUserMappingByGitlabUserId. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); + }); +} + +/** + * Get all repositories by project id + * @param {import('dynamoose').ModelConstructor} model The dynamoose model to query + * @param {String} projectId The project id + * @returns {Promise>} + */ +async function queryAllRepositoriesByProjectId(model, projectId) { + return await new Promise((resolve, reject) => { + model.scan({projectId: {eq: projectId}}) + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryAllRepositoriesByProjectId. Error. ${err}`); + return reject(err); + } + return resolve(result); + }); }); } @@ -335,13 +355,13 @@ async function queryOneActiveRepository(model, url) { url, archived: 'false' }) - .all() - .exec((err, result) => { - if (err) { - return reject(err); - } - return resolve(result); - }); + .all() + .exec((err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + }); }); } @@ -379,6 +399,7 @@ module.exports = { queryOneUserMappingByGitlabUsername, queryOneUserMappingByTCUsername, queryChallengeUUIDsByRepoUrl, + queryAllRepositoriesByProjectId, removeCopilotPayment, removeIssue }; diff --git a/utils/errors.js b/utils/errors.js index 81f6750..030c9fa 100644 --- a/utils/errors.js +++ b/utils/errors.js @@ -45,10 +45,10 @@ errors.handleGitHubError = function handleGitHubError(err, message, copilotHandl resMsg += ` Detail: ${detail}`; } const apiError = new ProcessorError( - _.get(err, 'response.status', constants.SERVICE_ERROR_STATUS), - resMsg, - 'github' - ); + _.get(err, 'response.status', constants.SERVICE_ERROR_STATUS), + resMsg, + 'github' + ); return apiError; }; @@ -70,10 +70,10 @@ errors.handleGitLabError = function handleGitLabError(err, message, copilotHandl resMsg += ` Detail: ${detail}`; } const apiError = new ProcessorError( - err.status || _.get(err, 'response.status', constants.SERVICE_ERROR_STATUS), - resMsg, - 'gitlab' - ); + err.status || _.get(err, 'response.status', constants.SERVICE_ERROR_STATUS), + resMsg, + 'gitlab' + ); return apiError; }; @@ -105,10 +105,10 @@ errors.convertTopcoderApiError = function convertTopcoderApiError(err, message) errors.internalDependencyError = function internalDependencyError(message) { const resMsg = `${message}`; const apiError = new ProcessorError( - constants.SERVICE_ERROR_STATUS, - resMsg, - 'processor' - ); + constants.SERVICE_ERROR_STATUS, + resMsg, + 'processor' + ); return apiError; }; diff --git a/utils/kafka-consumer.js b/utils/kafka-consumer.js index 30655a7..0023dc4 100644 --- a/utils/kafka-consumer.js +++ b/utils/kafka-consumer.js @@ -13,74 +13,84 @@ const healthcheck = require('topcoder-healthcheck-dropin'); const IssueService = require('../services/IssueService'); const CopilotPaymentService = require('../services/CopilotPaymentService'); const ChallengeService = require('../services/ChallengeService'); +const PrivateForkService = require('../services/PrivateForkService'); const NotificationService = require('../services/NotificationService'); const logger = require('./logger'); const kafka = require('./kafka'); /** - * Handle the message from kafka - * @param {Object} messageSet object to handle + * Parses the raw payload from a Kafka message + * @param {import('no-kafka').Message} event the message + * @returns {import('no-kafka').Message} */ -function messageHandler(messageSet) { - logger.debug(` topics ======= ${JSON.stringify(messageSet)}`); - messageSet.forEach((item) => { - // The event should be a JSON object - let event; +function parsePayload(event) { + try { + const _message = JSON.parse(event.message.value.toString('utf8')); + event.message.value = _message; + logger.debug(`Decoded message from kafka: ${JSON.stringify(_.omit(event, 'payload.value.data.issue.body'))}`); + return event; + } catch (err) { + logger.error('"message" is not a valid JSON-formatted string.', err); + return null; + } +} + +/** + * Handle the messages published to Topcoder-X topic of kafka + * @param {import('no-kafka').Message[]} messageSet the message set + */ +function tcxMessageHandler(messageSet, topic) { + logger.debug('Incoming message', {messageSet, topic}); + messageSet.forEach((event) => { + // The event should be a JSON object + event = parsePayload(event); try { - const message = JSON.parse(item.message.value.toString('utf8')); - event = JSON.parse(message.payload.value); - message.payload.value = event; - logger.debug(`received message from kafka: ${JSON.stringify(_.omit(message, 'payload.value.data.issue.body'))}`); - } catch (err) { - logger.error(`"message" is not a valid JSON-formatted string: ${err.message}`); + event.message.value.payload.value = JSON.parse(event.message.value.payload.value); + } catch (e) { + logger.error('Invalid message payload', e); return; } - - if (event && _.includes(['issue.created', 'issue.updated', 'issue.closed', 'issue.recreated', - 'comment.created', 'comment.updated', 'issue.assigned', 'issue.labelUpdated', 'issue.unassigned'] - , event.event)) { + const payload = event.message.value.payload.value; + logger.debug(`[kafka-consumer#tcxMessageHandler] Decoded Payload ${JSON.stringify(payload)}`); + if (_.includes(['issue.created', 'issue.updated', 'issue.closed', 'issue.recreated', + 'comment.created', 'comment.updated', 'issue.assigned', 'issue.labelUpdated', 'issue.unassigned'], payload.event)) { IssueService - .process(event) - .catch(logger.error); + .process(payload) + .catch(logger.error); } - if (event && _.includes(['copilotPayment.add', 'copilotPayment.update', 'copilotPayment.delete', 'copilotPayment.checkUpdates'] - , event.event)) { + if (_.includes(['copilotPayment.add', 'copilotPayment.update', 'copilotPayment.delete', 'copilotPayment.checkUpdates'] + , payload.event)) { CopilotPaymentService - .process(event) - .catch(logger.error); + .process(payload) + .catch(logger.error); } - if (event && _.includes(['challengeTags.update'] - , event.event)) { + if (_.includes(['challengeTags.update'] + , payload.event)) { ChallengeService - .process(event) - .catch(logger.error); + .process(payload) + .catch(logger.error); } - if (event && _.includes(['notification.tokenExpired'] - , event.event)) { + if (_.includes(['notification.tokenExpired'] + , payload.event)) { NotificationService - .process(event) - .catch(logger.error); + .process(payload) + .catch(logger.error); } }); } /** - * check if there is kafka connection alive - * @returns {Boolean} true + * Handle the message published to Challenge-Action-Resource-Created topic of Kafka + * @param {import('no-kafka').Message[]} messageSet the message set */ -function check() { - // if (!this.consumer.client.initialBrokers && !this.consumer.client.initialBrokers.length) { - // logger.info(`Brokers Exist Check Failed ${this.consumer.client.initialBrokers} ${this.consumer.client.initialBrokers.length}`) - // return false; - // } - // let connected = true; - // this.consumer.client.initialBrokers.forEach((conn) => { - // logger.info(`Brokers Check Failed ${conn.connected}`) - // connected = conn.connected && connected; - // }); - - // return connected; - return true; +function challengeResourceCreationHandler(messageSet, topic) { + logger.debug('Incoming message', {messageSet, topic}); + messageSet.forEach((event) => { + event = parsePayload(event); + const payload = event.message.value.payload; + logger.debug(`[kafka-consumer#challengeResourceCreationHandler] Decoded Payload ${JSON.stringify(payload)}`); + PrivateForkService.process(payload); + }); } /** @@ -89,8 +99,9 @@ function check() { function run() { kafka.consumer.init().then(() => { logger.info('kafka consumer is ready'); - healthcheck.init([check]); - kafka.consumer.subscribe(config.TOPIC, {}, messageHandler); + healthcheck.init(); + kafka.consumer.subscribe(config.TOPIC, {}, tcxMessageHandler); + kafka.consumer.subscribe(config.TOPIC_CHALLENGE_ACTION_RESOURCE_CREATE, {}, challengeResourceCreationHandler); }).catch((err) => { logger.error(`kafka consumer is not connected. ${err.stack}`); }); diff --git a/utils/kafka-sender.js b/utils/kafka-sender.js index a053456..47367d5 100644 --- a/utils/kafka-sender.js +++ b/utils/kafka-sender.js @@ -18,7 +18,7 @@ function send(message) { const data = JSON.stringify({ topic: config.TOPIC, originator: 'topcoder-x-processor', - timestamp: (new Date()).toISOString(), + timestamp: new Date().toISOString(), 'mime-type': 'application/json', payload: { value: message @@ -41,7 +41,7 @@ function sendNotification(notification) { const data = JSON.stringify({ topic: config.TOPIC_NOTIFICATION, originator: 'topcoder-x-processor', - timestamp: (new Date()).toISOString(), + timestamp: new Date().toISOString(), 'mime-type': 'application/json', payload: { notifications: [notification] From 33948336e2f5f94a1fed290ff3a4c12a74c09da5 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Fri, 25 Aug 2023 05:47:07 +0530 Subject: [PATCH 11/28] Remove extra logging call --- services/PrivateForkService.js | 1 - 1 file changed, 1 deletion(-) diff --git a/services/PrivateForkService.js b/services/PrivateForkService.js index 00e481c..5402a22 100644 --- a/services/PrivateForkService.js +++ b/services/PrivateForkService.js @@ -60,7 +60,6 @@ async function process(payload) { logger.debug(`${logPrefix}Project: ${JSON.stringify(project)}`); // Get Repositories const repositories = await dbHelper.queryAllRepositoriesByProjectId(Repository, project.id); - console.log(repositories); if (!repositories || repositories.length === 0) { logger.info(`${logPrefix}Repository not found for projectId: ${project.id}`); return; From 456d2332f3f3b42130fd77ff23ae70aeca4f3ec0 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Fri, 8 Sep 2023 10:08:51 +0530 Subject: [PATCH 12/28] fix: handle case of missing member in "Add User to Repository" flow --- services/GitlabService.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/services/GitlabService.js b/services/GitlabService.js index 6d24fd4..c58449f 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -345,7 +345,17 @@ async function getRepository(user, repoURL) { async function addUserToRepository(copilot, repository, user, accessLevel) { const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); const gitlab = await _authenticate(refreshedCopilot.accessToken); - const member = await gitlab.ProjectMembers.show(repository.id, user.userProviderId); + const member = await new Promise((resolve, reject) => { + gitlab.ProjectMembers.show(repository.id, user.userProviderId) + .then((result) => resolve(result)) + .catch((err) => { + // eslint-disable-next-line no-magic-numbers + if (_.get(err, 'cause.response.status') === 404) { + return resolve(null); + } + return reject(err); + }); + }); if (!member) { await gitlab.ProjectMembers.add(repository.id, user.userProviderId, accessLevel); return; @@ -386,16 +396,17 @@ async function _refreshGitlabUserAccessToken(copilot) { .end(); // save user token data const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; - return await dbHelper.update(models.User, copilot.id, { + const updates = { accessToken: refreshTokenResult.body.access_token, accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), refreshToken: refreshTokenResult.body.refresh_token - }); + }; + copilot = _.assign(copilot, updates); + return await dbHelper.update(models.User, copilot.id, updates); } return copilot; } - module.exports = { createComment, updateIssue, From 944ccbe24730b58d9b335cd2a6400e46104fd853 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Sun, 10 Sep 2023 18:09:39 +0530 Subject: [PATCH 13/28] fix: gitlab token renewal failure --- services/GitlabService.js | 152 +++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 69 deletions(-) diff --git a/services/GitlabService.js b/services/GitlabService.js index c58449f..9d0da3d 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -30,23 +30,59 @@ const copilotUserSchema = Joi.object().keys({ accessTokenExpiration: Joi.date().required(), refreshToken: Joi.string().required(), userProviderId: Joi.number().required(), - topcoderUsername: Joi.string() + topcoderUsername: Joi.string(), + username: Joi.string().optional(), + type: Joi.string().optional(), + id: Joi.string().optional(), + role: Joi.string().optional() }).required(); +/** + * Refresh the user access token if needed + * @param {Object} user the copilot + * @returns {Promise} the promise result of copilot with refreshed token + */ +async function _refreshAccessToken(user) { + if (user.accessTokenExpiration && new Date().getTime() > user.accessTokenExpiration.getTime() - + (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { + const refreshTokenResult = await request + .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) + .query({ + client_id: config.GITLAB_CLIENT_ID, + client_secret: config.GITLAB_CLIENT_SECRET, + refresh_token: user.refreshToken, + grant_type: 'refresh_token', + redirect_uri: config.GITLAB_OWNER_USER_CALLBACK_URL + }) + .end(); + // save user token data + const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; + const updates = { + accessToken: refreshTokenResult.body.access_token, + accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), + refreshToken: refreshTokenResult.body.refresh_token + }; + _.assign(user, updates); + await dbHelper.update(models.User, user.id, updates); + } + return user; +} + /** * authenticate the gitlab using access token - * @param {String} accessToken the access token of copilot + * @param {Object} user the user * @private */ -async function _authenticate(accessToken) { +async function _getClient(user) { try { + const refreshedUser = await _refreshAccessToken(user); const gitlab = new Gitlab({ host: config.GITLAB_API_BASE_URL, - oauthToken: accessToken + oauthToken: refreshedUser.accessToken }); return gitlab; } catch (err) { - throw errors.handleGitLabError(err, 'Failed to during authenticate to Github using access token of copilot.'); + throw errors.handleGitLabError(err, 'Failed to authenticate to Gitlab using access token of copilot.', err); } } @@ -89,8 +125,7 @@ function _getIssueUrl(repoPath, issueId) { async function createComment(copilot, project, issueId, body) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, body}, createComment.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); try { body = helper.prepareAutomatedComment(body, copilot); await gitlab.IssueNotes.create(projectId, issueId, body); @@ -117,8 +152,7 @@ createComment.schema = { async function updateIssue(copilot, project, issueId, title) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, title}, updateIssue.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); try { await gitlab.Issues.edit(projectId, issueId, {title}); } catch (err) { @@ -144,8 +178,7 @@ updateIssue.schema = { async function assignUser(copilot, project, issueId, userId) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, userId}, assignUser.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); try { const issue = await gitlab.Issues.show(issueId, {projectId}); const oldAssignees = _.without(issue.assignees.map((a) => a.id), userId); @@ -176,8 +209,7 @@ assignUser.schema = { async function removeAssign(copilot, project, issueId, userId) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, userId}, removeAssign.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); await _removeAssignees(gitlab, projectId, issueId, [userId]); logger.debug(`Gitlab user ${userId} is unassigned from issue number ${issueId}`); } @@ -192,8 +224,7 @@ removeAssign.schema = assignUser.schema; */ async function getUsernameById(copilot, userId) { Joi.attempt({copilot, userId}, getUsernameById.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); const user = await gitlab.Users.show(userId); return user ? user.username : null; } @@ -211,8 +242,7 @@ getUsernameById.schema = { */ async function getUserIdByLogin(copilot, login) { Joi.attempt({copilot, login}, getUserIdByLogin.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); const user = await gitlab.Users.all({username: login}); return user.length ? user[0].id : null; } @@ -235,8 +265,7 @@ getUserIdByLogin.schema = { async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params const projectId = project.id; Joi.attempt({copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments}, markIssueAsPaid.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL) .push(config.FIX_ACCEPTED_ISSUE_LABEL, config.PAID_ISSUE_LABEL).value(); try { @@ -279,8 +308,7 @@ markIssueAsPaid.schema = { async function changeState(copilot, project, issueId, state) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, state}, changeState.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); try { await gitlab.Issues.edit(projectId, issueId, {stateEvent: state}); } catch (err) { @@ -306,8 +334,7 @@ changeState.schema = { async function addLabels(copilot, project, issueId, labels) { const projectId = project.id; Joi.attempt({copilot, projectId, issueId, labels}, addLabels.schema); - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); + const gitlab = await _getClient(copilot); try { await gitlab.Issues.edit(projectId, issueId, {labels: _.join(labels, ',')}); } catch (err) { @@ -329,12 +356,17 @@ addLabels.schema = { * @param {Object} repoURL The repository URL */ async function getRepository(user, repoURL) { - const refreshedUser = await _refreshGitlabUserAccessToken(user); - const gitlab = await _authenticate(refreshedUser.accessToken); + Joi.attempt({user, repoURL}, getRepository.schema); + const gitlab = await _getClient(user); const _repoURL = repoURL.replace(`${config.GITLAB_API_BASE_URL}/`, ''); return await gitlab.Projects.show(_repoURL); } +getRepository.schema = { + user: Joi.object().required(), + repoURL: Joi.string().required() +}; + /** * Add a user to a gitlab repository * @param {Object} copilot The copilot @@ -343,18 +375,19 @@ async function getRepository(user, repoURL) { * @param {import('@gitbeaker/rest').AccessLevel} accessLevel The user role */ async function addUserToRepository(copilot, repository, user, accessLevel) { - const refreshedCopilot = await _refreshGitlabUserAccessToken(copilot); - const gitlab = await _authenticate(refreshedCopilot.accessToken); - const member = await new Promise((resolve, reject) => { - gitlab.ProjectMembers.show(repository.id, user.userProviderId) - .then((result) => resolve(result)) - .catch((err) => { - // eslint-disable-next-line no-magic-numbers - if (_.get(err, 'cause.response.status') === 404) { - return resolve(null); - } - return reject(err); - }); + Joi.attempt({copilot, repository, user, accessLevel}, addUserToRepository.schema); + const gitlab = await _getClient(copilot); + const member = await new Promise(async (resolve, reject) => { + try { + const res = await gitlab.ProjectMembers.show(repository.id, user.userProviderId); + resolve(res); + } catch (err) { + // eslint-disable-next-line no-magic-numbers + if (_.get(err, 'cause.response.status') === 404) { + resolve(null); + } + reject(err); + } }); if (!member) { await gitlab.ProjectMembers.add(repository.id, user.userProviderId, accessLevel); @@ -365,47 +398,28 @@ async function addUserToRepository(copilot, repository, user, accessLevel) { } } +addUserToRepository.schema = { + copilot: copilotUserSchema, + repository: Joi.object().required(), + user: Joi.object().required(), + accessLevel: Joi.number().required() +}; + /** * Fork a gitlab repository * @param {Object} user The user * @param {ProjectSchema} repository The repository */ async function forkRepository(user, repository) { - const refreshedUser = await _refreshGitlabUserAccessToken(user); - const gitlab = await _authenticate(refreshedUser.accessToken); + Joi.attempt({user, repository}, forkRepository.schema); + const gitlab = await _getClient(user); await gitlab.Projects.fork(repository.id); } -/** - * Refresh the copilot access token if token is needed - * @param {Object} copilot the copilot - * @returns {Promise} the promise result of copilot with refreshed token - */ -async function _refreshGitlabUserAccessToken(copilot) { - if (copilot.accessTokenExpiration && new Date().getTime() > copilot.accessTokenExpiration.getTime() - - (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { - const refreshTokenResult = await request - .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) - .query({ - client_id: config.GITLAB_CLIENT_ID, - client_secret: config.GITLAB_CLIENT_SECRET, - refresh_token: copilot.refreshToken, - grant_type: 'refresh_token', - redirect_uri: config.GITLAB_OWNER_USER_CALLBACK_URL - }) - .end(); - // save user token data - const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; - const updates = { - accessToken: refreshTokenResult.body.access_token, - accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), - refreshToken: refreshTokenResult.body.refresh_token - }; - copilot = _.assign(copilot, updates); - return await dbHelper.update(models.User, copilot.id, updates); - } - return copilot; -} +forkRepository.schema = { + user: Joi.object().required(), + repository: Joi.object().required() +}; module.exports = { createComment, From a579ba3aa9ec445f80b9146163b169add3fdc185 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Mon, 11 Sep 2023 15:54:04 +0530 Subject: [PATCH 14/28] Further enhancements for authentication issues --- .eslintrc | 4 +- config/default.js | 3 +- services/EventService.js | 12 +- services/GitlabService.js | 729 +++++++++++++++++---------------- services/PrivateForkService.js | 60 +-- utils/errors.js | 4 +- utils/logger.js | 18 +- 7 files changed, 421 insertions(+), 409 deletions(-) diff --git a/.eslintrc b/.eslintrc index a16e9ea..f85c154 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,7 @@ "jsdoc" ], "parserOptions": { - "ecmaVersion": 8, + "ecmaVersion": 2023, "ecmaFeatures": { "experimentalObjectRestSpread": true } @@ -45,6 +45,8 @@ "functions": "ignore" } ], + "import/no-unresolved": 0, + "max-params": 0, "max-lines": 0, "max-statements": 0, "valid-jsdoc": 0 diff --git a/config/default.js b/config/default.js index 68d4216..d62967a 100644 --- a/config/default.js +++ b/config/default.js @@ -80,5 +80,6 @@ module.exports = { GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION: 300, GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET: process.env.GITLAB_CLIENT_SECRET, - GITLAB_OWNER_USER_CALLBACK_URL: process.env.GITLAB_OWNER_USER_CALLBACK_URL + GITLAB_OWNER_USER_CALLBACK_URL: process.env.GITLAB_OWNER_USER_CALLBACK_URL, + GITLAB_GUEST_USER_CALLBACK_URL: process.env.GITLAB_GUEST_USER_CALLBACK_URL }; diff --git a/services/EventService.js b/services/EventService.js index d2cbece..3f66c9f 100644 --- a/services/EventService.js +++ b/services/EventService.js @@ -14,7 +14,7 @@ const logger = require('../utils/logger'); const models = require('../models'); const dbHelper = require('../utils/db-helper'); const gitHubService = require('./GithubService'); -const gitlabService = require('./GitlabService'); +const GitlabService = require('./GitlabService'); const timeoutMapper = {}; @@ -27,7 +27,8 @@ async function reOpenIssue(event, issue) { if (event.provider === 'github') { await gitHubService.changeState(event.copilot, event.data.repository.full_name, issue.number, 'open'); } else if (event.provider === 'gitlab') { - await gitlabService.changeState(event.copilot, event.data.repository.id, issue.number, 'reopen'); + const gitlabService = await GitlabService.create(event.copilot); + await gitlabService.changeState(event.data.repository.id, issue.number, 'reopen'); } } @@ -37,7 +38,7 @@ async function reOpenIssue(event, issue) { * @param {Object} data the issue data or the copilot payment data * @param {Object} err the error */ -async function handleEventGracefully(event, data, err) { +async function handleEventGracefully(event, data, err) { // eslint-disable-line complexity if (err.errorAt === 'topcoder' || err.errorAt === 'processor') { event.retryCount = _.toInteger(event.retryCount); let keyName = ''; @@ -64,7 +65,7 @@ async function handleEventGracefully(event, data, err) { if (event.retryCount === config.RETRY_COUNT) { // Clear out the kafka queue of any queued messages (assignment, label changes, etc...) const timeoutsToClear = timeoutMapper[keyName]; - for (let i = 0; i < timeoutsToClear.length; i++) { // eslint-disable-line no-restricted-syntax + for (let i = 0; i < timeoutsToClear.length; i++) { // eslint-disable-line no-restricted-syntax clearTimeout(timeoutsToClear[i]); } let comment = `[${err.statusCode}]: ${err.message}`; @@ -95,7 +96,8 @@ async function handleEventGracefully(event, data, err) { if (event.provider === 'github') { await gitHubService.createComment(event.copilot, event.data.repository.full_name, data.number, comment); } else if (event.provider === 'gitlab') { - await gitlabService.createComment(event.copilot, event.data.repository.id, data.number, comment); + const gitlabService = await GitlabService.create(event.copilot); + await gitlabService.createComment(event.data.repository.id, data.number, comment); } if (event.event === 'issue.closed') { diff --git a/services/GitlabService.js b/services/GitlabService.js index 9d0da3d..b580036 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -22,418 +22,419 @@ const helper = require('../utils/helper'); const dbHelper = require('../utils/db-helper'); const request = superagentPromise(superagent, Promise); + // milliseconds per second const MS_PER_SECOND = 1000; -const copilotUserSchema = Joi.object().keys({ + +const USER_ROLE_TO_REDIRECT_URI_MAP = { + owner: config.GITLAB_OWNER_USER_CALLBACK_URL, + guest: config.GITLAB_GUEST_USER_CALLBACK_URL +}; + +/** + * A schema for a Gitlab user, as stored in the TCX database. + * @typedef {Object} User + * @property {String} accessToken the access token + * @property {Date} accessTokenExpiration the access token expiration date + * @property {String} refreshToken the refresh token + * @property {Number} userProviderId the user provider id + * @property {String} topcoderUsername the topcoder username + * @property {String} username the username + * @property {String} type the type + * @property {String} id the id + * @property {String} role the role + */ + +const USER_SCHEMA = Joi.object().keys({ accessToken: Joi.string().required(), accessTokenExpiration: Joi.date().required(), refreshToken: Joi.string().required(), userProviderId: Joi.number().required(), topcoderUsername: Joi.string(), username: Joi.string().optional(), - type: Joi.string().optional(), + type: Joi.string().valid('gitlab').required(), id: Joi.string().optional(), - role: Joi.string().optional() + role: Joi.string().valid('owner', 'guest').required() }).required(); /** - * Refresh the user access token if needed - * @param {Object} user the copilot - * @returns {Promise} the promise result of copilot with refreshed token + * @typedef {Object} ProjectWithId + * @property {Number} id the project id */ -async function _refreshAccessToken(user) { - if (user.accessTokenExpiration && new Date().getTime() > user.accessTokenExpiration.getTime() - - (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { - const refreshTokenResult = await request - .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) - .query({ - client_id: config.GITLAB_CLIENT_ID, - client_secret: config.GITLAB_CLIENT_SECRET, - refresh_token: user.refreshToken, - grant_type: 'refresh_token', - redirect_uri: config.GITLAB_OWNER_USER_CALLBACK_URL - }) - .end(); - // save user token data - const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; - const updates = { - accessToken: refreshTokenResult.body.access_token, - accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), - refreshToken: refreshTokenResult.body.refresh_token - }; - _.assign(user, updates); - await dbHelper.update(models.User, user.id, updates); - } - return user; -} -/** - * authenticate the gitlab using access token - * @param {Object} user the user - * @private - */ -async function _getClient(user) { - try { - const refreshedUser = await _refreshAccessToken(user); - const gitlab = new Gitlab({ - host: config.GITLAB_API_BASE_URL, - oauthToken: refreshedUser.accessToken - }); - return gitlab; - } catch (err) { - throw errors.handleGitLabError(err, 'Failed to authenticate to Gitlab using access token of copilot.', err); - } -} +const PROJECT_WITH_ID_SCHEMA = Joi.object().keys({ + id: Joi.number().positive().required() +}).unknown(true).required(); -/** - * Removes assignees from issue - * @param {import('@gitbeaker/core').Gitlab} gitlab the gitlab instance - * @param {Number} projectId the project id - * @param {Number} issueId the issue number - * @param {Array} assignees the users to remove - * @private - */ -async function _removeAssignees(gitlab, projectId, issueId, assignees) { - try { - const issue = await gitlab.Issues.show(issueId, {projectId}); - const oldAssignees = _.difference(issue.assignee_ids, assignees); - await gitlab.Issues.edit(projectId, issueId, {assigneeIds: oldAssignees}); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during remove assignees from issue.'); - } -} +class GitlabService { + /** @type {User} */ + #user = null; -/** - * Get gitlab issue url - * @param {String} repoPath the repo path - * @param {Number} issueId the issue number - * @returns {String} the url - * @private - */ -function _getIssueUrl(repoPath, issueId) { - return `https://gitlab.com/${repoPath}/issues/${issueId}`; -} + /** @type {Gitlab} */ + #gitlab = null; -/** - * creates the comments on gitlab issue - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue number - * @param {string} body the comment body text - */ -async function createComment(copilot, project, issueId, body) { - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, body}, createComment.schema); - const gitlab = await _getClient(copilot); - try { - body = helper.prepareAutomatedComment(body, copilot); - await gitlab.IssueNotes.create(projectId, issueId, body); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during creating comment on issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); + constructor(user) { + if (!user) { + throw new Error('User is required.'); + } + Joi.attempt(user, USER_SCHEMA); + this.#user = user; } - logger.debug(`Gitlab comment is added on issue with message: "${body}"`); -} -createComment.schema = { - copilot: copilotUserSchema, - projectId: Joi.number().positive().required(), - issueId: Joi.number().positive().required(), - body: Joi.string().required() -}; - -/** - * updates the title of gitlab issue - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue number - * @param {string} title new title - */ -async function updateIssue(copilot, project, issueId, title) { - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, title}, updateIssue.schema); - const gitlab = await _getClient(copilot); - try { - await gitlab.Issues.edit(projectId, issueId, {title}); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during updating issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); + /** + * Helper method for initializing a GitlabService instance with an active + * access token. + * @param {User} user the user + * @returns {Promise} the GitlabService instance + */ + static async create(user) { + const svc = new GitlabService(user); + try { + await svc.refreshAccessToken(); + svc.#gitlab = new Gitlab({ + host: config.GITLAB_API_BASE_URL, + oauthToken: user.accessToken + }); + return svc; + } catch (err) { + throw errors.handleGitLabError(err, 'Authentication failed for Gitlab user'); + } } - logger.debug(`Gitlab issue title is updated for issue number ${issueId}`); -} -updateIssue.schema = { - copilot: copilotUserSchema, - projectId: Joi.number().positive().required(), - issueId: Joi.number().positive().required(), - title: Joi.string().required() -}; -/** - * Assigns the issue to user login - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue number - * @param {Number} userId the user id of assignee - */ -async function assignUser(copilot, project, issueId, userId) { - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, userId}, assignUser.schema); - const gitlab = await _getClient(copilot); - try { - const issue = await gitlab.Issues.show(issueId, {projectId}); - const oldAssignees = _.without(issue.assignees.map((a) => a.id), userId); - if (oldAssignees && oldAssignees.length > 0) { - await _removeAssignees(gitlab, projectId, issueId, oldAssignees); + /** + * Refresh the user access token if needed + */ + async refreshAccessToken() { + const user = this.#user; + if (user.accessTokenExpiration && new Date().getTime() > user.accessTokenExpiration.getTime() - + (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { + const query = { + client_id: config.GITLAB_CLIENT_ID, + client_secret: config.GITLAB_CLIENT_SECRET, + refresh_token: user.refreshToken, + grant_type: 'refresh_token', + redirect_uri: USER_ROLE_TO_REDIRECT_URI_MAP[user.role] + }; + const refreshTokenResult = await request + .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) + .query(query) + .end(); + // save user token data + const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; + const updates = { + accessToken: refreshTokenResult.body.access_token, + accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), + refreshToken: refreshTokenResult.body.refresh_token + }; + _.assign(user, updates); + await dbHelper.update(models.User, user.id, updates); } - await gitlab.Issues.edit(projectId, issueId, {assigneeIds: [userId]}); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during assigning issue user.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); + return user; } - logger.debug(`Gitlab issue with number ${issueId} is assigned to ${issueId}`); -} - -assignUser.schema = { - copilot: copilotUserSchema, - projectId: Joi.number().positive().required(), - issueId: Joi.number().positive().required(), - userId: Joi.number().required() -}; - -/** - * Removes an assignee from the issue - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue number - * @param {Number} userId the user id of assignee to remove - */ -async function removeAssign(copilot, project, issueId, userId) { - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, userId}, removeAssign.schema); - const gitlab = await _getClient(copilot); - await _removeAssignees(gitlab, projectId, issueId, [userId]); - logger.debug(`Gitlab user ${userId} is unassigned from issue number ${issueId}`); -} - -removeAssign.schema = assignUser.schema; - -/** - * Gets the user name by user id - * @param {Object} copilot the copilot - * @param {Number} userId the user id - * @returns {string} the username if found else null - */ -async function getUsernameById(copilot, userId) { - Joi.attempt({copilot, userId}, getUsernameById.schema); - const gitlab = await _getClient(copilot); - const user = await gitlab.Users.show(userId); - return user ? user.username : null; -} - -getUsernameById.schema = { - copilot: copilotUserSchema, - userId: Joi.number().required() -}; -/** - * Gets the user id by username - * @param {Object} copilot the copilot - * @param {string} login the username - * @returns {Number} the user id if found else null - */ -async function getUserIdByLogin(copilot, login) { - Joi.attempt({copilot, login}, getUserIdByLogin.schema); - const gitlab = await _getClient(copilot); - const user = await gitlab.Users.all({username: login}); - return user.length ? user[0].id : null; -} + /** + * Removes assignees from issue + * @param {Number} projectId the project id + * @param {Number} issueId the issue number + * @param {Array} assignees the users to remove + * @private + */ + async #removeAssignees(projectId, issueId, assignees) { + try { + const issue = await this.#gitlab.Issues.show(issueId, {projectId}); + const oldAssignees = _.difference(issue.assignee_ids, assignees); + await this.#gitlab.Issues.edit(projectId, issueId, {assigneeIds: oldAssignees}); + } catch (err) { + throw errors.handleGitLabError(err, 'Error occurred during remove assignees from issue.'); + } + } -getUserIdByLogin.schema = { - copilot: copilotUserSchema, - login: Joi.string().required() -}; + /** + * Get gitlab issue url + * @param {String} repoPath the repo path + * @param {Number} issueId the issue number + * @returns {String} the url + * @private + */ + #getIssueUrl(repoPath, issueId) { + return `https://gitlab.com/${repoPath}/issues/${issueId}`; + } -/** - * updates the gitlab issue as paid and fix accepted - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue number - * @param {String} challengeUUID the challenge uuid - * @param {Array} existLabels the issue labels - * @param {String} winner the winner topcoder handle - * @param {Boolean} createCopilotPayments the option to create copilot payments or not - */ -async function markIssueAsPaid(copilot, project, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { // eslint-disable-line max-params - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, challengeUUID, existLabels, winner, createCopilotPayments}, markIssueAsPaid.schema); - const gitlab = await _getClient(copilot); - const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL) - .push(config.FIX_ACCEPTED_ISSUE_LABEL, config.PAID_ISSUE_LABEL).value(); - try { - await gitlab.Issues.edit(projectId, issueId, {labels}); - let commentMessage = ''; - - commentMessage += `Payment task has been updated: ${config.TC_URL}/challenges/${challengeUUID}\n\n`; - commentMessage += '*Payments Complete*\n\n'; - commentMessage += `Winner: ${winner}\n\n`; - if (createCopilotPayments) { - commentMessage += `Copilot: ${copilot.topcoderUsername}\n\n`; + /** + * creates the comments on gitlab issue + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue number + * @param {String} body the comment body text + */ + async createComment(project, issueId, body) { + Joi.attempt({project, issueId, body}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + body: Joi.string().required() + }); + const projectId = project.id; + try { + body = helper.prepareAutomatedComment(body, this.#user); + await this.#gitlab.IssueNotes.create(projectId, issueId, body); + } catch (err) { + throw errors.handleGitLabError( + err, + 'Error occurred during creating comment on issue.', + this.#user.topcoderUsername, + this.#getIssueUrl(project.full_name, issueId) + ); } - commentMessage += `Challenge \`${challengeUUID}\` has been paid and closed.`; + logger.debug(`Gitlab comment is added on issue with message: "${body}"`); + } - const body = helper.prepareAutomatedComment(commentMessage, copilot); - await gitlab.IssueNotes.create(projectId, issueId, body); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during updating issue as paid.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); + /** + * updates the title of gitlab issue + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue number + * @param {String} title new title + */ + async updateIssue(project, issueId, title) { + Joi.attempt({project, issueId, title}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + title: Joi.string().required() + }); + const projectId = project.id; + try { + await this.#gitlab.Issues.edit(projectId, issueId, {title}); + } catch (err) { + throw errors.handleGitLabError( + err, + 'Error occurred during updating issue.', + this.#user.topcoderUsername, + this.#getIssueUrl(project.full_name, issueId) + ); + } + logger.debug(`Gitlab issue title is updated for issue number ${issueId}`); } - logger.debug(`Gitlab issue is updated for as paid and fix accepted for ${issueId}`); -} -markIssueAsPaid.schema = { - copilot: copilotUserSchema, - projectId: Joi.number().positive().required(), - issueId: Joi.number().positive().required(), - challengeUUID: Joi.string().required(), - existLabels: Joi.array().items(Joi.string()).required(), - winner: Joi.string().required(), - createCopilotPayments: Joi.boolean().default(false).optional() -}; + /** + * Assigns the issue to user login + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue number + * @param {Number} userId the user id of assignee + */ + async assignUser(project, issueId, userId) { + Joi.attempt({project, issueId, userId}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + userId: Joi.number().required() + }); + const projectId = project.id; + try { + const issue = await this.#gitlab.Issues.show(issueId, {projectId}); + const oldAssignees = _.without(issue.assignees.map((a) => a.id), userId); + if (oldAssignees && oldAssignees.length > 0) { + await this.#removeAssignees(projectId, issueId, oldAssignees); + } + await this.#gitlab.Issues.edit(projectId, issueId, {assigneeIds: [userId]}); + } catch (err) { + throw errors.handleGitLabError( + err, + 'Error occurred during assigning issue user.', + this.#user.topcoderUsername, + this.#getIssueUrl(project.full_name, issueId) + ); + } + logger.debug(`Gitlab issue with number ${issueId} is assigned to ${issueId}`); + } -/** - * change the state of gitlab issue - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue issue id - * @param {string} state new state - */ -async function changeState(copilot, project, issueId, state) { - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, state}, changeState.schema); - const gitlab = await _getClient(copilot); - try { - await gitlab.Issues.edit(projectId, issueId, {stateEvent: state}); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during updating status of issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); + /** + * Removes an assignee from the issue + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue number + * @param {Number} userId the user id of assignee to remove + */ + async removeAssign(project, issueId, userId) { + Joi.attempt({project, issueId, userId}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + userId: Joi.number().required() + }); + const projectId = project.id; + await this.#removeAssignees(projectId, issueId, [userId]); + logger.debug(`Gitlab user ${userId} is unassigned from issue number ${issueId}`); } - logger.debug(`Gitlab issue state is updated to '${state}' for issue number ${issueId}`); -} -changeState.schema = { - copilot: copilotUserSchema, - projectId: Joi.number().positive().required(), - issueId: Joi.number().positive().required(), - state: Joi.string().required() -}; + /** + * Gets the user name by user id + * @param {Number} userId the user id + * @returns {string} the username if found else null + */ + async getUsernameById(userId) { + Joi.attempt({userId}, {userId: Joi.number().required()}); + const user = await this.#gitlab.Users.show(userId); + return user ? user.username : null; + } -/** - * updates the gitlab issue with new labels - * @param {Object} copilot the copilot - * @param {Object} project the project object - * @param {Number} issueId the issue issue id - * @param {Number} labels the labels - */ -async function addLabels(copilot, project, issueId, labels) { - const projectId = project.id; - Joi.attempt({copilot, projectId, issueId, labels}, addLabels.schema); - const gitlab = await _getClient(copilot); - try { - await gitlab.Issues.edit(projectId, issueId, {labels: _.join(labels, ',')}); - } catch (err) { - throw errors.handleGitLabError(err, 'Error occurred during adding label in issue.', copilot.topcoderUsername, _getIssueUrl(project.full_name, issueId)); + /** + * Gets the user id by username + * @param {String} login the username + * @returns {Number} the user id if found else null + */ + async getUserIdByLogin(login) { + Joi.attempt({login}, {login: Joi.string().required()}); + const user = await this.#gitlab.Users.all({username: login}); + return user.length ? user[0].id : null; } - logger.debug(`Gitlab issue is updated with new labels for ${issueId}`); -} -addLabels.schema = { - copilot: copilotUserSchema, - projectId: Joi.number().positive().required(), - issueId: Joi.number().required(), - labels: Joi.array().items(Joi.string()).required() -}; + /** updates the gitlab issue as paid and fix accepted + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue number + * @param {String} challengeUUID the challenge uuid + * @param {Array} existLabels the issue labels + * @param {String} winner the winner topcoder handle + * @param {Boolean} createCopilotPayments the option to create copilot payments or not + */ + async markIssueAsPaid(project, issueId, challengeUUID, existLabels, winner, createCopilotPayments) { + Joi.attempt({project, issueId, challengeUUID, existLabels, winner, createCopilotPayments}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + challengeUUID: Joi.string().required(), + existLabels: Joi.array().items(Joi.string()).required(), + winner: Joi.string().required(), + createCopilotPayments: Joi.boolean().default(false).optional() + }); + const projectId = project.id; + const labels = _(existLabels).filter((i) => i !== config.FIX_ACCEPTED_ISSUE_LABEL) + .push(config.FIX_ACCEPTED_ISSUE_LABEL, config.PAID_ISSUE_LABEL).value(); + try { + await this.#gitlab.Issues.edit(projectId, issueId, {labels}); + let commentMessage = ''; + + commentMessage += `Payment task has been updated: ${config.TC_URL}/challenges/${challengeUUID}\n\n`; + commentMessage += '*Payments Complete*\n\n'; + commentMessage += `Winner: ${winner}\n\n`; + if (createCopilotPayments) { + commentMessage += `Copilot: ${this.#user.topcoderUsername}\n\n`; + } + commentMessage += `Challenge \`${challengeUUID}\` has been paid and closed.`; -/** - * Get gitlab repository - * @param {Object} user The user - * @param {Object} repoURL The repository URL - */ -async function getRepository(user, repoURL) { - Joi.attempt({user, repoURL}, getRepository.schema); - const gitlab = await _getClient(user); - const _repoURL = repoURL.replace(`${config.GITLAB_API_BASE_URL}/`, ''); - return await gitlab.Projects.show(_repoURL); -} + const body = helper.prepareAutomatedComment(commentMessage, this.#user); + await this.#gitlab.IssueNotes.create(projectId, issueId, body); + } catch (err) { + throw errors.handleGitLabError( + err, + 'Error occurred during updating issue as paid.', + this.#user.topcoderUsername, + this.#getIssueUrl(project.full_name, issueId) + ); + } + logger.debug(`Gitlab issue is updated for as paid and fix accepted for ${issueId}`); + } -getRepository.schema = { - user: Joi.object().required(), - repoURL: Joi.string().required() -}; + /** + * change the state of gitlab issue + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue issue id + * @param {string} state new state + */ + async changeState(project, issueId, state) { + Joi.attempt({project, issueId, state}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + state: Joi.string().required() + }); + const projectId = project.id; + try { + await this.#gitlab.Issues.edit(projectId, issueId, {stateEvent: state}); + } catch (err) { + throw errors.handleGitLabError( + err, + 'Error occurred during updating status of issue.', + this.#user.topcoderUsername, + this.#getIssueUrl(project.full_name, issueId) + ); + } + logger.debug(`Gitlab issue state is updated to '${state}' for issue number ${issueId}`); + } -/** - * Add a user to a gitlab repository - * @param {Object} copilot The copilot - * @param {import('@gitbeaker/rest').ProjectSchema} repository The repository - * @param {Object} user The user - * @param {import('@gitbeaker/rest').AccessLevel} accessLevel The user role - */ -async function addUserToRepository(copilot, repository, user, accessLevel) { - Joi.attempt({copilot, repository, user, accessLevel}, addUserToRepository.schema); - const gitlab = await _getClient(copilot); - const member = await new Promise(async (resolve, reject) => { + /** + * updates the gitlab issue with new labels + * @param {ProjectWithId} project the project object + * @param {Number} issueId the issue issue id + * @param {Number} labels the labels + */ + async addLabels(project, issueId, labels) { + Joi.attempt({project, issueId, labels}, { + project: PROJECT_WITH_ID_SCHEMA, + issueId: Joi.number().positive().required(), + labels: Joi.array().items(Joi.string()).required() + }); + const projectId = project.id; try { - const res = await gitlab.ProjectMembers.show(repository.id, user.userProviderId); - resolve(res); + await this.#gitlab.Issues.edit(projectId, issueId, {labels: _.join(labels, ',')}); } catch (err) { - // eslint-disable-next-line no-magic-numbers - if (_.get(err, 'cause.response.status') === 404) { - resolve(null); - } - reject(err); + throw errors.handleGitLabError( + err, + 'Error occurred during adding label in issue.', + this.#user.topcoderUsername, + this.#getIssueUrl(project.full_name, issueId) + ); } - }); - if (!member) { - await gitlab.ProjectMembers.add(repository.id, user.userProviderId, accessLevel); - return; + logger.debug(`Gitlab issue is updated with new labels for ${issueId}`); } - if (member.access_level !== accessLevel) { - await gitlab.ProjectMembers.edit(repository.id, user.userProviderId, accessLevel); + + /** + * Get gitlab repository + * @param {String} repoURL The repository URL + */ + async getRepository(repoURL) { + Joi.attempt({repoURL}, {repoURL: Joi.string().required()}); + const _repoURL = repoURL.replace(`${config.GITLAB_API_BASE_URL}/`, ''); + return await this.#gitlab.Projects.show(_repoURL); } -} -addUserToRepository.schema = { - copilot: copilotUserSchema, - repository: Joi.object().required(), - user: Joi.object().required(), - accessLevel: Joi.number().required() -}; + /** + * Add a user to a gitlab repository + * @param {import('@gitbeaker/rest').ProjectSchema} repository The repository + * @param {User} user The user + * @param {import('@gitbeaker/rest').AccessLevel} accessLevel The user role + */ + async addUserToRepository(repository, user, accessLevel) { + Joi.attempt({repository, user, accessLevel}, { + repository: Joi.object().required(), + user: Joi.object().required(), + accessLevel: Joi.number().required() + }); + const member = await new Promise(async (resolve, reject) => { + try { + const res = await this.#gitlab.ProjectMembers.show(repository.id, user.userProviderId); + resolve(res); + } catch (err) { + // eslint-disable-next-line no-magic-numbers + if (_.get(err, 'cause.response.status') === 404) { + resolve(null); + } + reject(err); + } + }); + if (!member) { + await this.#gitlab.ProjectMembers.add(repository.id, user.userProviderId, accessLevel); + return; + } + if (member.access_level !== accessLevel) { + await this.#gitlab.ProjectMembers.edit(repository.id, user.userProviderId, accessLevel); + } + } -/** - * Fork a gitlab repository - * @param {Object} user The user - * @param {ProjectSchema} repository The repository - */ -async function forkRepository(user, repository) { - Joi.attempt({user, repository}, forkRepository.schema); - const gitlab = await _getClient(user); - await gitlab.Projects.fork(repository.id); + /** + * Fork a gitlab repository + * @param {ProjectSchema} repository The repository + */ + async forkRepository(repository) { + Joi.attempt({repository}, {repository: Joi.object().required()}); + await this.#gitlab.Projects.fork(repository.id); + } } -forkRepository.schema = { - user: Joi.object().required(), - repository: Joi.object().required() -}; - -module.exports = { - createComment, - updateIssue, - assignUser, - removeAssign, - getUsernameById, - getUserIdByLogin, - markIssueAsPaid, - changeState, - addLabels, - getRepository, - addUserToRepository, - forkRepository -}; +module.exports = GitlabService; -logger.buildService(module.exports); +logger.buildService(module.exports, true); diff --git a/services/PrivateForkService.js b/services/PrivateForkService.js index 5402a22..195dac0 100644 --- a/services/PrivateForkService.js +++ b/services/PrivateForkService.js @@ -1,16 +1,8 @@ -/* eslint-disable no-magic-numbers */ -/* - * Copyright (c) 2018 TopCoder, Inc. All rights reserved. - */ 'use strict'; +/* eslint-disable no-magic-numbers */ -/** - * This service will provide project operations. - * - * @author TCSCODER - * @version 1.0 - */ const Joi = require('joi'); +const uuid = require('uuid').v4; const models = require('../models'); const dbHelper = require('../utils/db-helper'); const logger = require('../utils/logger'); @@ -32,7 +24,11 @@ const GitlabUserMapping = models.GitlabUserMapping; */ async function process(payload) { const {challengeId, memberId, memberHandle} = payload; - const logPrefix = `[PrivateForkService#handleUserRegistration (challengeId: ${challengeId}, memberId: ${memberId}, memberHandle: ${memberHandle})]: `; + const correlationId = uuid(); + const logPrefix = `[${correlationId}][PullRequestService#process]`; + logger.debug(`${logPrefix}: Challenge ID: ${challengeId}`); + logger.debug(`${logPrefix}: Member ID: ${memberId}`); + logger.debug(`${logPrefix}: Member Handle: ${memberHandle}`); // Check if there are projects mapped to the challenge const filterValues = {}; const filter = { @@ -46,66 +42,70 @@ async function process(payload) { }; const projectChallengeMapping = await dbHelper.scan(ProjectChallengeMapping, filter, filterValues); if (projectChallengeMapping.length === 0) { - logger.info(`${logPrefix}ProjectChallengeMapping not found for challengeId: ${challengeId}`); + logger.info(`${logPrefix} ProjectChallengeMapping not found for challengeId: ${challengeId}`); return; } - logger.debug(`${logPrefix}ProjectChallengeMapping: ${JSON.stringify(projectChallengeMapping)}`); + logger.debug(`${logPrefix} ProjectChallengeMapping: ${JSON.stringify(projectChallengeMapping)}`); // Get Project const projectId = projectChallengeMapping[0].projectId; const project = await dbHelper.getById(Project, projectId); if (!project) { - logger.info(`${logPrefix}Project not found for projectId: ${projectId}`); + logger.info(`${logPrefix} Project not found for projectId: ${projectId}`); return; } - logger.debug(`${logPrefix}Project: ${JSON.stringify(project)}`); + logger.debug(`${logPrefix} Project: ${JSON.stringify(project)}`); // Get Repositories const repositories = await dbHelper.queryAllRepositoriesByProjectId(Repository, project.id); if (!repositories || repositories.length === 0) { - logger.info(`${logPrefix}Repository not found for projectId: ${project.id}`); + logger.info(`${logPrefix} Repository not found for projectId: ${project.id}`); return; } - logger.debug(`${logPrefix}Repository: ${JSON.stringify(repositories)}`); + logger.debug(`${logPrefix} Repository: ${JSON.stringify(repositories)}`); // Get Co-pilot GitlabUserMapping const copilotGitlabUserMapping = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, project.copilot); if (!copilotGitlabUserMapping) { - logger.info(`${logPrefix}GitlabUserMapping not found for copilot: ${project.copilot}`); + logger.info(`${logPrefix} GitlabUserMapping not found for copilot: ${project.copilot}`); return; } - logger.debug(`${logPrefix}GitlabUserMapping[Copilot]: ${JSON.stringify(copilotGitlabUserMapping)}`); + logger.debug(`${logPrefix} GitlabUserMapping[Copilot]: ${JSON.stringify(copilotGitlabUserMapping)}`); // Get Gitlab User const copilotGitlabUser = await dbHelper.queryOneUserByType(User, copilotGitlabUserMapping.gitlabUsername, 'gitlab'); if (!copilotGitlabUser) { - logger.info(`${logPrefix}GitlabUser not found for copilot: ${project.copilot}`); + logger.info(`${logPrefix} GitlabUser not found for copilot: ${project.copilot}`); return; } - logger.debug(`${logPrefix}GitlabUser[Copilot]: ${JSON.stringify(copilotGitlabUser)}`); + logger.debug(`${logPrefix} GitlabUser[Copilot]: ${JSON.stringify(copilotGitlabUser)}`); + // Initialize Copilot Gitlab Service + const copilotGitlabService = await GitlabService.create(copilotGitlabUser); // Get Member GitlabUserMapping const memberGitlabUserMapping = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, memberHandle); if (!memberGitlabUserMapping) { - logger.info(`${logPrefix}GitlabUserMapping not found for memberHandle: ${memberHandle}`); + logger.info(`${logPrefix} GitlabUserMapping not found for memberHandle: ${memberHandle}`); return; } - logger.debug(`${logPrefix}GitlabUserMapping[Member]: ${JSON.stringify(memberGitlabUserMapping)}`); + logger.debug(`${logPrefix} GitlabUserMapping[Member]: ${JSON.stringify(memberGitlabUserMapping)}`); // Get Gitlab User const memberGitlabUser = await dbHelper.queryOneUserByType(User, memberGitlabUserMapping.gitlabUsername, 'gitlab'); if (!memberGitlabUser) { - logger.info(`${logPrefix}GitlabUser not found for memberHandle: ${memberHandle}`); + logger.info(`${logPrefix} GitlabUser not found for memberHandle: ${memberHandle}`); return; } - logger.debug(`${logPrefix}GitlabUser[Member]: ${JSON.stringify(memberGitlabUser)}`); + logger.debug(`${logPrefix} GitlabUser[Member]: ${JSON.stringify(memberGitlabUser)}`); + // Initialize Member Gitlab Service + const memberGitlabService = await GitlabService.create(memberGitlabUser); await Promise.all(repositories.map(async (repo) => { try { - const repository = await GitlabService.getRepository(copilotGitlabUser, repo.url); + const repository = await memberGitlabService.getRepository(repo.url); if (!repository) { - logger.info(`${logPrefix}Repository not found for repo: ${repo}`); + logger.info(`${logPrefix} Repository not found for repo: ${repo}`); return; } // Add user as a guest to the repo - await GitlabService.addUserToRepository(copilotGitlabUser, repository, memberGitlabUser, GITLAB_ACCESS_LEVELS.DEVELOPER); + await copilotGitlabService.addUserToRepository(repository, memberGitlabUser, GITLAB_ACCESS_LEVELS.DEVELOPER); // Fork the repository - await GitlabService.forkRepository(memberGitlabUser, repository); + await memberGitlabService.forkRepository(repository); } catch (err) { - logger.error(`${logPrefix}Error: ${err.message}`, err); + logger.error(`${logPrefix} Error: ${err.message}`, err); } })); } diff --git a/utils/errors.js b/utils/errors.js index 030c9fa..63ecf65 100644 --- a/utils/errors.js +++ b/utils/errors.js @@ -65,9 +65,9 @@ errors.handleGitLabError = function handleGitLabError(err, message, copilotHandl notification.sendTokenExpiredAlert(copilotHandle, repoPath, 'Gitlab'); } let resMsg = `${message}. ${err.message}.`; - const detail = _.get(err, 'response.body.message'); + const detail = _.get(err, 'response.body') || _.get(err, 'cause.response.body'); if (detail) { - resMsg += ` Detail: ${detail}`; + resMsg += ` Response Body: ${JSON.stringify(detail)}`; } const apiError = new ProcessorError( err.status || _.get(err, 'response.status', constants.SERVICE_ERROR_STATUS), diff --git a/utils/logger.js b/utils/logger.js index 4477578..473b392 100644 --- a/utils/logger.js +++ b/utils/logger.js @@ -64,12 +64,12 @@ function sanitizeObject(obj) { * Decorate all functions of a service and log debug information if DEBUG is enabled * @param {Object} service the service */ -logger.decorateWithLogging = function decorateWithLogging(service) { +logger.decorateWithLogging = function decorateWithLogging(service, isClass = false) { if (config.LOG_LEVEL !== 'debug') { return; } - _.forEach(service, (method, name) => { - service[name] = async function serviceMethodWithLogging() { + const forEachIteratee = (method, name, obj) => { + obj[name] = async function serviceMethodWithLogging() { try { const result = await method.apply(this, arguments); // eslint-disable-line return result; @@ -78,15 +78,21 @@ logger.decorateWithLogging = function decorateWithLogging(service) { throw e; } }; - }); + }; + if (isClass) { + _.forEach(service.prototype, forEachIteratee); + } else { + _.forEach(service, forEachIteratee); + } }; /** * Apply logger and validation decorators * @param {Object} service the service to wrap + * @param {Boolean} isClass whether the service is an ES6 class */ -logger.buildService = function buildService(service) { - logger.decorateWithLogging(service); +logger.buildService = function buildService(service, isClass = false) { + logger.decorateWithLogging(service, isClass); }; /** From 8893ff99b0c0accffb0f78f2af370fd1e8eba992 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Tue, 12 Sep 2023 03:46:43 +0530 Subject: [PATCH 15/28] fix: lock table for refreshing Gitlab token --- constants.js | 3 +- models/User.js | 4 +- package-lock.json | 29 +++---- package.json | 5 +- services/GitlabService.js | 136 +++++++++++++++++++++++------- services/PrivateForkService.js | 18 ++-- services/PullRequestService.js | 148 +++++++++++++++++++++++++++++++++ utils/db-helper.js | 119 +++++++++++++++++++++++++- utils/errors.js | 2 +- utils/kafka-consumer.js | 7 ++ utils/topcoder-api-helper.js | 3 + 11 files changed, 413 insertions(+), 61 deletions(-) create mode 100644 services/PullRequestService.js diff --git a/constants.js b/constants.js index cb32c76..dcdd16f 100644 --- a/constants.js +++ b/constants.js @@ -19,7 +19,8 @@ const USER_TYPES = { // The user roles const USER_ROLES = { - OWNER: 'owner' + OWNER: 'owner', + GUEST: 'guest' }; // The challenge status diff --git a/models/User.js b/models/User.js index dc3ca69..7237dfe 100755 --- a/models/User.js +++ b/models/User.js @@ -49,7 +49,9 @@ const schema = new Schema({ // gitlab token data accessToken: {type: String, required: false}, accessTokenExpiration: {type: Date, required: false}, - refreshToken: {type: String, required: false} + refreshToken: {type: String, required: false}, + lockId: {type: String, required: false}, + lockExpiration: {type: Date, required: false} }); module.exports = schema; diff --git a/package-lock.json b/package-lock.json index 74bde4c..929ac63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@gitbeaker/rest": "^39.12.0", + "@gitbeaker/rest": "^39.13.0", "@octokit/rest": "^18.9.0", "axios": "^0.19.0", "circular-json": "^0.5.7", @@ -46,7 +46,8 @@ "uuid": "^3.3.2" }, "engines": { - "node": "~8.6.0" + "node": ">=20", + "npm": ">=9" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -204,11 +205,11 @@ } }, "node_modules/@gitbeaker/core": { - "version": "39.12.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-39.12.0.tgz", - "integrity": "sha512-c/LQl+UI+rXjXx+P+kLrdTOZnyD/RdhRWnkuBE8b8/dwfvnJ3ANEv1WBZhVJpTwn6miHlurERiOeLmKeQJ+J6w==", + "version": "39.13.0", + "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-39.13.0.tgz", + "integrity": "sha512-L+QhR1xQiWPSLjfzYuUgs3b+YLgYBUIMjWCYdd+31HzCiqMC80nBRTqPx4vH3A4rtYciZM5EL3xcl6txjVZ0EQ==", "dependencies": { - "@gitbeaker/requester-utils": "^39.12.0", + "@gitbeaker/requester-utils": "^39.13.0", "qs": "^6.11.2", "xcase": "^2.0.1" }, @@ -231,9 +232,9 @@ } }, "node_modules/@gitbeaker/requester-utils": { - "version": "39.12.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-39.12.0.tgz", - "integrity": "sha512-0016Xnt6xIO3kSUuJ/mcXyN8LWUMpqAmLFbXZWMzJ9YZpQHX9vPKsrFHz4/P9Dh9eWKoAnkjEXEf/F6w1gX6Dg==", + "version": "39.13.0", + "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-39.13.0.tgz", + "integrity": "sha512-TKzbN9znKCjtAvHbksGian3/qS2CT0PL7RKLm3arBQB3WlRz/JhvekL/X773VVEOi/AZt45T5DlZjFHGtTj3Eg==", "dependencies": { "qs": "^6.11.2", "xcase": "^2.0.1" @@ -257,12 +258,12 @@ } }, "node_modules/@gitbeaker/rest": { - "version": "39.12.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-39.12.0.tgz", - "integrity": "sha512-PILr042hCuB/A/QE7IGQ0ADTMN1e8lvehEfZEQEp78aWlqyNFmi6IUZqL6q8v3Stu6WRKSRcMCOidY83hiCSsA==", + "version": "39.13.0", + "resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-39.13.0.tgz", + "integrity": "sha512-pGqNLUX32BWHKbx2M8UsRN7irHPq730m0YFPlzeCBGi/5OYDapoIiGJeIYS12Dc8BJBiHJahVjG5pNnMBGfDBg==", "dependencies": { - "@gitbeaker/core": "^39.12.0", - "@gitbeaker/requester-utils": "^39.12.0" + "@gitbeaker/core": "^39.13.0", + "@gitbeaker/requester-utils": "^39.13.0" }, "engines": { "node": ">=18.0.0" diff --git a/package.json b/package.json index 974ad42..5d74f99 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "direct-connect-migration": "node scripts/direct-connect-migration.js" }, "engines": { - "node": "~8.6.0" + "node": ">=20", + "npm": ">=9" }, "repository": { "type": "git", @@ -26,7 +27,7 @@ }, "homepage": "https://gitlab.com/luettich/processor#README", "dependencies": { - "@gitbeaker/rest": "^39.12.0", + "@gitbeaker/rest": "^39.13.0", "@octokit/rest": "^18.9.0", "axios": "^0.19.0", "circular-json": "^0.5.7", diff --git a/services/GitlabService.js b/services/GitlabService.js index b580036..1fce8ed 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -8,8 +8,8 @@ * @author TCSCODER * @version 1.0 */ - const config = require('config'); +const uuid = require('uuid').v4; const _ = require('lodash'); const Joi = require('joi'); const {Gitlab} = require('@gitbeaker/rest'); @@ -26,11 +26,11 @@ const request = superagentPromise(superagent, Promise); // milliseconds per second const MS_PER_SECOND = 1000; +const LOCK_TTL_SECONDS = 20; + +const MAX_RETRY_COUNT = 30; -const USER_ROLE_TO_REDIRECT_URI_MAP = { - owner: config.GITLAB_OWNER_USER_CALLBACK_URL, - guest: config.GITLAB_GUEST_USER_CALLBACK_URL -}; +const COOLDOWN_TIME = 1000; /** * A schema for a Gitlab user, as stored in the TCX database. @@ -55,7 +55,9 @@ const USER_SCHEMA = Joi.object().keys({ username: Joi.string().optional(), type: Joi.string().valid('gitlab').required(), id: Joi.string().optional(), - role: Joi.string().valid('owner', 'guest').required() + role: Joi.string().valid('owner', 'guest').required(), + lockId: Joi.string().optional(), + lockExpiration: Joi.date().optional() }).required(); /** @@ -107,31 +109,51 @@ class GitlabService { * Refresh the user access token if needed */ async refreshAccessToken() { - const user = this.#user; - if (user.accessTokenExpiration && new Date().getTime() > user.accessTokenExpiration.getTime() - - (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { - const query = { - client_id: config.GITLAB_CLIENT_ID, - client_secret: config.GITLAB_CLIENT_SECRET, - refresh_token: user.refreshToken, - grant_type: 'refresh_token', - redirect_uri: USER_ROLE_TO_REDIRECT_URI_MAP[user.role] - }; - const refreshTokenResult = await request - .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) - .query(query) - .end(); - // save user token data - const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; - const updates = { - accessToken: refreshTokenResult.body.access_token, - accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), - refreshToken: refreshTokenResult.body.refresh_token - }; - _.assign(user, updates); - await dbHelper.update(models.User, user.id, updates); + const lockId = uuid().replace(/-/g, ''); + let lockedUser; + let tries = 0; + try { + // eslint-disable-next-line no-constant-condition, no-restricted-syntax + while ((tries < MAX_RETRY_COUNT) && !(lockedUser && lockedUser.lockId === lockId)) { + logger.debug(`[Lock ID: ${lockId}][Attempt #${tries + 1}] Acquiring lock on user ${this.#user.username}.`); + lockedUser = await dbHelper.acquireLockOnUser(this.#user.id, lockId, LOCK_TTL_SECONDS * MS_PER_SECOND); + await new Promise((resolve) => setTimeout(resolve, COOLDOWN_TIME)); + tries += 1; + } + if (!lockedUser) { + throw new Error(`Failed to acquire lock on user ${this.#user.id} after ${tries} attempts.`); + } + logger.debug(`[Lock ID: ${lockId}] Acquired lock on user ${this.#user.id}.`); + if (lockedUser.accessTokenExpiration && new Date().getTime() > lockedUser.accessTokenExpiration.getTime() - + (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { + logger.debug(`[Lock ID: ${lockId}] Refreshing access token for user ${this.#user.id}.`); + const query = { + client_id: config.GITLAB_CLIENT_ID, + client_secret: config.GITLAB_CLIENT_SECRET, + refresh_token: lockedUser.refreshToken, + grant_type: 'refresh_token' + }; + const refreshTokenResult = await request + .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) + .query(query) + .end(); + // save user token data + const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; + const updates = { + accessToken: refreshTokenResult.body.access_token, + accessTokenExpiration: new Date(new Date().getTime() + expiresIn * MS_PER_SECOND), + refreshToken: refreshTokenResult.body.refresh_token + }; + _.assign(lockedUser, updates); + await dbHelper.update(models.User, lockedUser.id, updates); + } + return lockedUser; + } finally { + if (lockedUser) { + logger.debug(`[Lock ID: ${lockId}] Releasing lock on user ${this.#user.id}.`); + await dbHelper.releaseLockOnUser(this.#user.id, lockId); + } } - return user; } /** @@ -433,6 +455,60 @@ class GitlabService { Joi.attempt({repository}, {repository: Joi.object().required()}); await this.#gitlab.Projects.fork(repository.id); } + + /** + * Get the diff patch for a gitlab merge request + * @param {import('@gitbeaker/rest').MergeRequestSchemaWithBasicLabels} mergeRequest The merge request + * @returns {Promise} The diff patch + */ + async getMergeRequestDiffPatches(mergeRequest) { + Joi.attempt({mergeRequest}, { + mergeRequest: Joi.object().keys({ + web_url: Joi.string().required() + }).unknown(true).required() + }); + const diff = await this.#gitlab.MergeRequests.allDiffs(mergeRequest.target_project_id, mergeRequest.iid); + const patchFile = diff.reduce((acc, file) => { + // Header + acc += `diff --git a/${file.old_path} b/${file.new_path}\n`; + // Index + if (file.new_file) { + acc += `new file mode ${file.b_mode}\n`; + } + if (file.deleted_file) { + acc += `deleted file mode ${file.a_mode}\n`; + } + if (file.diff && file.diff !== '') { + acc += `--- a/${file.new_file ? '/dev/null' : file.old_path}\n`; + acc += `+++ b/${file.deleted_file ? '/dev/null' : file.new_path}\n`; + acc += file.diff; + } else if (file.renamed_file) { + acc += 'similarity index 100%\n'; + acc += `rename from ${file.old_path}\n`; + acc += `rename to ${file.new_path}\n`; + } + return acc; + }, ''); + console.log(patchFile); + return patchFile; + } + + /** + * Get a list of all merge requests for a gitlab repository + * @param {ProjectSchema} repository The repository + * @param {Number} userId + */ + async getOpenMergeRequestsByUser(repository, userId) { + Joi.attempt({repository, userId}, { + repository: Joi.object().required(), + userId: Joi.number().required() + }); + return this.#gitlab.MergeRequests.all({ + projectId: repository.id, + state: 'opened', + authorId: userId + }); + } } module.exports = GitlabService; diff --git a/services/PrivateForkService.js b/services/PrivateForkService.js index 195dac0..4d24411 100644 --- a/services/PrivateForkService.js +++ b/services/PrivateForkService.js @@ -6,12 +6,12 @@ const uuid = require('uuid').v4; const models = require('../models'); const dbHelper = require('../utils/db-helper'); const logger = require('../utils/logger'); +const errors = require('../utils/errors'); const GitlabService = require('../services/GitlabService'); -const {GITLAB_ACCESS_LEVELS} = require('../constants'); +const {GITLAB_ACCESS_LEVELS, USER_ROLES, USER_TYPES} = require('../constants'); const ProjectChallengeMapping = models.ProjectChallengeMapping; const Project = models.Project; -const Repository = models.Repository; const User = models.User; const GitlabUserMapping = models.GitlabUserMapping; @@ -25,7 +25,7 @@ const GitlabUserMapping = models.GitlabUserMapping; async function process(payload) { const {challengeId, memberId, memberHandle} = payload; const correlationId = uuid(); - const logPrefix = `[${correlationId}][PullRequestService#process]`; + const logPrefix = `[Correlation ID: ${correlationId}][PullRequestService#process]`; logger.debug(`${logPrefix}: Challenge ID: ${challengeId}`); logger.debug(`${logPrefix}: Member ID: ${memberId}`); logger.debug(`${logPrefix}: Member Handle: ${memberHandle}`); @@ -55,7 +55,7 @@ async function process(payload) { } logger.debug(`${logPrefix} Project: ${JSON.stringify(project)}`); // Get Repositories - const repositories = await dbHelper.queryAllRepositoriesByProjectId(Repository, project.id); + const repositories = await dbHelper.queryAllRepositoriesByProjectId(project.id); if (!repositories || repositories.length === 0) { logger.info(`${logPrefix} Repository not found for projectId: ${project.id}`); return; @@ -69,9 +69,9 @@ async function process(payload) { } logger.debug(`${logPrefix} GitlabUserMapping[Copilot]: ${JSON.stringify(copilotGitlabUserMapping)}`); // Get Gitlab User - const copilotGitlabUser = await dbHelper.queryOneUserByType(User, copilotGitlabUserMapping.gitlabUsername, 'gitlab'); + const copilotGitlabUser = await dbHelper.queryOneUserByTypeAndRole(User, copilotGitlabUserMapping.gitlabUsername, USER_TYPES.GITLAB, USER_ROLES.OWNER); if (!copilotGitlabUser) { - logger.info(`${logPrefix} GitlabUser not found for copilot: ${project.copilot}`); + logger.info(`${logPrefix} User[Type=${USER_TYPES.GITLAB}, Role=${USER_ROLES.OWNER}] not found for copilot: ${project.copilot}`); return; } logger.debug(`${logPrefix} GitlabUser[Copilot]: ${JSON.stringify(copilotGitlabUser)}`); @@ -85,7 +85,7 @@ async function process(payload) { } logger.debug(`${logPrefix} GitlabUserMapping[Member]: ${JSON.stringify(memberGitlabUserMapping)}`); // Get Gitlab User - const memberGitlabUser = await dbHelper.queryOneUserByType(User, memberGitlabUserMapping.gitlabUsername, 'gitlab'); + const memberGitlabUser = await dbHelper.queryOneUserByTypeAndRole(User, memberGitlabUserMapping.gitlabUsername, USER_TYPES.GITLAB, USER_ROLES.GUEST); if (!memberGitlabUser) { logger.info(`${logPrefix} GitlabUser not found for memberHandle: ${memberHandle}`); return; @@ -102,10 +102,12 @@ async function process(payload) { } // Add user as a guest to the repo await copilotGitlabService.addUserToRepository(repository, memberGitlabUser, GITLAB_ACCESS_LEVELS.DEVELOPER); + logger.debug(`${logPrefix} User (${memberGitlabUser.username}) added to repository (${repo.url})`); // Fork the repository await memberGitlabService.forkRepository(repository); + logger.debug(`${logPrefix} Repository (${repo.url}) forked for user: ${memberGitlabUser.username}`); } catch (err) { - logger.error(`${logPrefix} Error: ${err.message}`, err); + throw errors.handleGitLabError(err, 'Error occurred while forking repository to user\'s namespace in GitLab'); } })); } diff --git a/services/PullRequestService.js b/services/PullRequestService.js new file mode 100644 index 0000000..5cc37c9 --- /dev/null +++ b/services/PullRequestService.js @@ -0,0 +1,148 @@ +'use strict'; + +const _ = require('lodash'); +const Joi = require('joi'); +const uuid = require('uuid').v4; +const models = require('../models'); +const dbHelper = require('../utils/db-helper'); +const logger = require('../utils/logger'); +const GitlabService = require('../services/GitlabService'); + +const GitlabUserMapping = models.GitlabUserMapping; + +/** + * Handles a pull request creation event. + * @param {Object} payload The event payload. + * @param {String} payload.provider The provider (gitlab or github) + * @param {Object} payload.data The event payload. + * @param {Object} payload.data.pull_request The pull request. + * @param {Number} payload.data.pull_request.number The pull request number. + * @param {Number} payload.data.pull_request.id The pull request id. + * @param {Object} payload.data.pull_request.merged The pull request merged flag. + * @param {Object} payload.data.pull_request.body The pull request body. + * @param {Object} payload.data.pull_request.title The pull request title. + * @param {Object} payload.data.pull_request.user The pull request user. + * @param {Number} payload.data.pull_request.user.id The pull request user id. + * @param {Object} payload.data.repository The repository. + * @param {Number} payload.data.repository.id The repository id. + * @param {String} payload.data.repository.name The repository name. + * @param {String} payload.data.repository.full_name The repository full name. + */ +async function process(payload) { + const {provider, data: {pull_request: pullRequest, repository}} = payload; + const {number: prNumber, id, user} = pullRequest; + const {id: userId} = user; + const {id: repoId, name: repoName, full_name: repoFullName} = repository; + const correlationId = uuid(); + const logPrefix = `[${correlationId}][PullRequestService#process]`; + logger.debug(`${logPrefix}: Provider: ${provider}`); + logger.debug(`${logPrefix}: PR Number: ${prNumber}`); + logger.debug(`${logPrefix}: PR Id: ${id}`); + logger.debug(`${logPrefix}: User Id: ${userId}`); + logger.debug(`${logPrefix}: Repo Id: ${repoId}`); + logger.debug(`${logPrefix}: Repo Name: ${repoName}`); + logger.debug(`${logPrefix}: Repo Full Name: ${repoFullName}`); + // 1. Find the TCX user using the GitLab user id (if not found, return) + const submitter = await dbHelper.queryOneUserMappingByGitlabUserId(GitlabUserMapping, userId); + if (!submitter) { + logger.info(`${logPrefix} GitlabUserMapping not found for userId: ${userId}`); + return; + } + logger.debug(`${logPrefix} GitlabUserMapping[Submitter]: ${JSON.stringify(submitter)}`); + // 2. Get the full GitLab project link + const gitlabProjectLink = await GitlabService.getRepoUrl(repoFullName); + logger.debug(`${logPrefix} GitLab project link: ${gitlabProjectLink}`); + // 3. Find the TCX project using the GitLab project link (if not found, return) + const project = await dbHelper.queryOneProjectByRepositoryLink(gitlabProjectLink); + if (!project) { + logger.info(`${logPrefix} Project not found for gitlabProjectLink: ${gitlabProjectLink}`); + return; + } + logger.debug(`${logPrefix} Project: ${JSON.stringify(project)}`); + // 4. Find all repositories corresponding to the TCX project + const repositories = await dbHelper.queryAllRepositoriesByProjectId(project.id); + if (!repositories || repositories.length === 0) { + logger.info(`${logPrefix} Repositories not found for projectId: ${project.id}`); + return; + } + logger.debug(`${logPrefix} Repositories: ${JSON.stringify(repositories)}`); + // 5. Get co-pilot's GitlabUserMapping + const copilot = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, project.copilot); + if (!copilot) { + logger.info(`${logPrefix} GitlabUserMapping not found for copilot: ${project.copilot}`); + return; + } + logger.debug(`${logPrefix} GitlabUserMapping[Copilot]: ${JSON.stringify(copilot)}`); + // 6. Get co-pilot's Gitlab user + const copilotGitlabUser = await dbHelper.queryOneUserByType(models.User, copilot.gitlabUsername, 'gitlab'); + if (!copilotGitlabUser) { + logger.info(`${logPrefix} GitlabUser not found for copilot: ${project.copilot}`); + return; + } + logger.debug(`${logPrefix} GitlabUser[Copilot]: ${JSON.stringify(copilotGitlabUser)}`); + // 7. For each project, get the repositories + const gitRepositories = await Promise.all(repositories.map((repo) => GitlabService.getRepository(copilotGitlabUser, repo.url))); + if (!gitRepositories || gitRepositories.length === 0) { + logger.info(`${logPrefix} Git repositories not found for repositories: ${JSON.stringify(repositories)}`); + return; + } + logger.debug(`${logPrefix} Git repositories: ${JSON.stringify(gitRepositories)}`); + // 8. For each repository, get the merge requests + const mergeRequests = await Promise.all( + gitRepositories.map((repo) => GitlabService.getOpenMergeRequestsByUser(copilotGitlabUser, repo, submitter.gitlabUserId)) + ); + if (!mergeRequests || mergeRequests.length === 0) { + logger.info(`${logPrefix} Merge requests not found for repositories: ${JSON.stringify(gitRepositories)}`); + return; + } + logger.debug(`${logPrefix} Merge requests: ${JSON.stringify(mergeRequests)}`); + // 9. Ensure that there exists a merge request by the same member as the pull request for each project (if not, return) + // eslint-disable-next-line no-restricted-syntax + for (let i = 0; i < mergeRequests.length; i += 1) { + const mr = mergeRequests[i]; + if (!mr || mr.length === 0) { + logger.info(`${logPrefix} Merge request not found for repository: ${gitRepositories[i].web_url}`); + return; + } + } + // 10. Get the latest merge request for each project + const latestMergeRequests = mergeRequests.map((mrs) => _.maxBy(mrs, (mr) => new Date(mr.created_at).getTime())); + logger.debug(`${logPrefix} Latest merge requests: ${JSON.stringify(latestMergeRequests)}`); + // 11. Create patch files for each merge request + const patches = await Promise.all( + latestMergeRequests.map((mr) => GitlabService.getMergeRequestDiffPatches(copilotGitlabUser, mr)) + ); + if (!patches || patches.length !== latestMergeRequests.length) { + logger.info(`${logPrefix} Patches not found for merge requests.`); + return; + } + logger.debug(`${logPrefix} Patches: ${JSON.stringify(patches)}`); + // 11. Get the topcoder M2M token + // 10. Create a zip file containing all patch files + // 11. Use the submission API to submit the zip file +} + +process.schema = Joi.object().keys({ + event: Joi.string().valid('pull_request.created').required(), + provider: Joi.string().valid('gitlab').required(), + data: Joi.object().keys({ + pullRequest: Joi.object().keys({ + number: Joi.number().required(), + id: Joi.number().required(), + user: Joi.object().keys({ + id: Joi.number().required() + }).required(), + repository: Joi.object().keys({ + id: Joi.number().required(), + name: Joi.string().required(), + full_name: Joi.string().required() + }).required() + }).required() + }).required() +}); + +module.exports = { + process +}; + +logger.buildService(module.exports); diff --git a/utils/db-helper.js b/utils/db-helper.js index 37fb949..18e7f35 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -122,6 +122,67 @@ async function queryOneUserByType(model, username, type) { }); } +/** + * Get single data by query parameters + * @param {Object} model The dynamoose model to query + * @param {String} username The user username + * @param {String} type The type of user + * @param {String} role The role of user + * @returns {Promise} + */ +async function queryOneUserByTypeAndRole(model, username, type, role) { + return await new Promise((resolve, reject) => { + model.query('username').eq(username) + .where('type') + .eq(type) + .all() + .exec((err, result) => { + if (err || !result) { + logger.debug(`queryOneUserByType. Error. ${err}`); + return reject(err); + } + const filteredResult = result.filter((item) => item.role === role); + return resolve(filteredResult.count === 0 ? null : filteredResult[0]); + }); + }); +} + +/** + * Query project by repository url + * @param {String} repoUrl the repo url + * @returns {Promise} + */ +async function queryOneProjectByRepositoryLink(repoUrl) { + const projectId = await new Promise((resolve, reject) => { + models.Repository.query('url') + .eq(repoUrl) + .all() + .exec((err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + }); + }); + if (!projectId || projectId.length === 0) { + return null; + } + return await new Promise((resolve, reject) => { + models.Project.queryOne('id') + .eq(projectId[0].projectId) + .all() + .exec((err, result) => { + if (err) { + return reject(err); + } + if (!result || result.length === 0) { + return resolve(null); + } + return resolve(result); + }); + }); +} + /** * Get single data by query parameters * @param {Object} model The dynamoose model to query @@ -224,13 +285,12 @@ async function queryOneUserMappingByGitlabUserId(model, userId) { /** * Get all repositories by project id - * @param {import('dynamoose').ModelConstructor} model The dynamoose model to query * @param {String} projectId The project id * @returns {Promise>} */ -async function queryAllRepositoriesByProjectId(model, projectId) { +async function queryAllRepositoriesByProjectId(projectId) { return await new Promise((resolve, reject) => { - model.scan({projectId: {eq: projectId}}) + models.Repository.scan({projectId: {eq: projectId}}) .all() .exec((err, result) => { if (err || !result) { @@ -383,6 +443,53 @@ async function queryChallengeUUIDsByRepoUrl(repoUrl) { }); } +/** + * Acquire lock on user to prevent concurrent updates + * @param {String} userId ID of the user + * @param {String} lockId ID of the lock + * @param {Number} ttl Time to live (in milliseconds) + * @returns {Promise} The lock object + */ +async function acquireLockOnUser(userId, lockId, ttl) { + const lockExpiration = Date.now() + ttl; + return await new Promise(async (resolve) => { + try { + const res = await models.User.update( + {id: userId}, + {lockId, lockExpiration}, + { + condition: 'attribute_not_exists(lockId) OR (lockExpiration < :lockExpiration)', + conditionValues: {lockExpiration: new Date()}, + returnValues: 'ALL_NEW' + }, + ); + return resolve(res); + } catch (err) { + if (err.code === 'ConditionalCheckFailedException') { + return resolve(null); + } + throw err; + } + }); +} +/** + * Release lock on user + * @param {String} id ID of the user + * @param {String} lockId ID of the lock + * @returns {Promise} The lock object + */ +async function releaseLockOnUser(id, lockId) { + const res = await models.User.update( + {id}, + {lockId: null, lockExpiration: null}, + { + condition: 'lockId = :lockId', + conditionValues: {lockId} + }, + ); + return res; +} + module.exports = { getById, scan, @@ -397,9 +504,13 @@ module.exports = { queryOneUserMappingByGitlabUserId, queryOneUserMappingByGithubUsername, queryOneUserMappingByGitlabUsername, + queryOneUserByTypeAndRole, + queryOneProjectByRepositoryLink, queryOneUserMappingByTCUsername, queryChallengeUUIDsByRepoUrl, queryAllRepositoriesByProjectId, removeCopilotPayment, - removeIssue + removeIssue, + acquireLockOnUser, + releaseLockOnUser }; diff --git a/utils/errors.js b/utils/errors.js index 63ecf65..fe04aa0 100644 --- a/utils/errors.js +++ b/utils/errors.js @@ -64,7 +64,7 @@ errors.handleGitLabError = function handleGitLabError(err, message, copilotHandl if (err.statusCode === 401 && copilotHandle && repoPath) { // eslint-disable-line no-magic-numbers notification.sendTokenExpiredAlert(copilotHandle, repoPath, 'Gitlab'); } - let resMsg = `${message}. ${err.message}.`; + let resMsg = `${message}: ${err.message}.`; const detail = _.get(err, 'response.body') || _.get(err, 'cause.response.body'); if (detail) { resMsg += ` Response Body: ${JSON.stringify(detail)}`; diff --git a/utils/kafka-consumer.js b/utils/kafka-consumer.js index 0023dc4..fe061bc 100644 --- a/utils/kafka-consumer.js +++ b/utils/kafka-consumer.js @@ -15,6 +15,7 @@ const CopilotPaymentService = require('../services/CopilotPaymentService'); const ChallengeService = require('../services/ChallengeService'); const PrivateForkService = require('../services/PrivateForkService'); const NotificationService = require('../services/NotificationService'); +const PullRequestService = require('../services/PullRequestService'); const logger = require('./logger'); const kafka = require('./kafka'); @@ -45,6 +46,7 @@ function tcxMessageHandler(messageSet, topic) { // The event should be a JSON object event = parsePayload(event); try { + console.log(event); event.message.value.payload.value = JSON.parse(event.message.value.payload.value); } catch (e) { logger.error('Invalid message payload', e); @@ -76,6 +78,11 @@ function tcxMessageHandler(messageSet, topic) { .process(payload) .catch(logger.error); } + if (_.includes(['pull_request.created'], payload.event)) { + PullRequestService + .process(payload) + .catch(logger.error); + } }); } diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index ade67d0..de63381 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -465,6 +465,9 @@ async function getProjectByDirectId(id, directId) { }); } +async function createSubmission(challengeId, submissionFileStream, submissionFileName, submissionType) { + // TODO: Implement submission creation +} module.exports = { createProject, From 472942707479271ab9e6e9244a1c5a053b229865 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Tue, 12 Sep 2023 11:27:02 +0530 Subject: [PATCH 16/28] fix: don't use expired token for gitlab client init --- services/GitlabService.js | 11 +++++------ utils/db-helper.js | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/services/GitlabService.js b/services/GitlabService.js index 1fce8ed..57e6307 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -96,7 +96,7 @@ class GitlabService { await svc.refreshAccessToken(); svc.#gitlab = new Gitlab({ host: config.GITLAB_API_BASE_URL, - oauthToken: user.accessToken + oauthToken: svc.#user.accessToken }); return svc; } catch (err) { @@ -123,10 +123,10 @@ class GitlabService { if (!lockedUser) { throw new Error(`Failed to acquire lock on user ${this.#user.id} after ${tries} attempts.`); } - logger.debug(`[Lock ID: ${lockId}] Acquired lock on user ${this.#user.id}.`); + logger.debug(`[Lock ID: ${lockId}] Acquired lock on user ${this.#user.username}.`); if (lockedUser.accessTokenExpiration && new Date().getTime() > lockedUser.accessTokenExpiration.getTime() - (config.GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION * MS_PER_SECOND)) { - logger.debug(`[Lock ID: ${lockId}] Refreshing access token for user ${this.#user.id}.`); + logger.debug(`[Lock ID: ${lockId}] Refreshing access token for user ${this.#user.username}.`); const query = { client_id: config.GITLAB_CLIENT_ID, client_secret: config.GITLAB_CLIENT_SECRET, @@ -147,11 +147,10 @@ class GitlabService { _.assign(lockedUser, updates); await dbHelper.update(models.User, lockedUser.id, updates); } - return lockedUser; } finally { if (lockedUser) { - logger.debug(`[Lock ID: ${lockId}] Releasing lock on user ${this.#user.id}.`); - await dbHelper.releaseLockOnUser(this.#user.id, lockId); + logger.debug(`[Lock ID: ${lockId}] Releasing lock on user ${this.#user.username}.`); + this.#user = await dbHelper.releaseLockOnUser(this.#user.id, lockId); } } } diff --git a/utils/db-helper.js b/utils/db-helper.js index 18e7f35..873fca6 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -479,7 +479,7 @@ async function acquireLockOnUser(userId, lockId, ttl) { * @returns {Promise} The lock object */ async function releaseLockOnUser(id, lockId) { - const res = await models.User.update( + const user = await models.User.update( {id}, {lockId: null, lockExpiration: null}, { @@ -487,7 +487,7 @@ async function releaseLockOnUser(id, lockId) { conditionValues: {lockId} }, ); - return res; + return user; } module.exports = { From 2cc1d4dab2a9658ba53b0c525e47655c7e7b5e00 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Wed, 13 Sep 2023 10:49:07 +0530 Subject: [PATCH 17/28] fix: update git-helper for refactored GitlabService --- services/GithubService.js | 8 ++++---- services/GitlabService.js | 4 ++-- utils/git-helper.js | 13 +++++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/services/GithubService.js b/services/GithubService.js index 6f2eafe..87e8713 100644 --- a/services/GithubService.js +++ b/services/GithubService.js @@ -43,7 +43,7 @@ function _parseRepoUrl(fullName) { /** * authenticate the github using access token * @param {String} accessToken the access token of copilot - * @returns {Object} the github instance + * @returns {Promise} the github instance * @private */ async function _authenticate(accessToken) { @@ -82,7 +82,7 @@ async function _removeAssignees(github, owner, repo, number, assignees) { /** * gets the username of given user id * @param {Number} id the user id - * @returns {string} username if found + * @returns {Promise} username if found */ async function _getUsernameById(id) { const user = await request @@ -211,7 +211,7 @@ createComment.schema = { * Gets the user name by user id * @param {Object} copilot the copilot * @param {Number} userId the user id - * @returns {string} the username if found else null + * @returns {Promise} the username if found else null */ async function getUsernameById(copilot, userId) { Joi.attempt({copilot, userId}, getUsernameById.schema); @@ -228,7 +228,7 @@ getUsernameById.schema = { * Gets the user id by username * @param {Object} copilot the copilot * @param {string} login the username - * @returns {Number} the user id if found else null + * @returns {Promise} the user id if found else null */ async function getUserIdByLogin(copilot, login) { Joi.attempt({copilot, login}, getUserIdByLogin.schema); diff --git a/services/GitlabService.js b/services/GitlabService.js index 57e6307..8dd94db 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -287,7 +287,7 @@ class GitlabService { /** * Gets the user name by user id * @param {Number} userId the user id - * @returns {string} the username if found else null + * @returns {Promise} the username if found else null */ async getUsernameById(userId) { Joi.attempt({userId}, {userId: Joi.number().required()}); @@ -298,7 +298,7 @@ class GitlabService { /** * Gets the user id by username * @param {String} login the username - * @returns {Number} the user id if found else null + * @returns {Promise} the user id if found else null */ async getUserIdByLogin(login) { Joi.attempt({login}, {login: Joi.string().required()}); diff --git a/utils/git-helper.js b/utils/git-helper.js index cc53626..2c90631 100644 --- a/utils/git-helper.js +++ b/utils/git-helper.js @@ -13,7 +13,7 @@ const config = require('config'); const gitHubService = require('../services/GithubService'); -const gitlabService = require('../services/GitlabService'); +const GitlabService = require('../services/GitlabService'); const azureService = require('../services/AzureService'); class GitHelper { @@ -27,6 +27,7 @@ class GitHelper { if (event.provider === 'github') { await gitHubService.createComment(event.copilot, event.data.repository.full_name, issueNumber, comment); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); await gitlabService.createComment(event.copilot, event.data.repository, issueNumber, comment); } } @@ -41,6 +42,7 @@ class GitHelper { if (event.provider === 'github') { await gitHubService.addLabels(event.copilot, event.data.repository.full_name, issueNumber, labels); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); await gitlabService.addLabels(event.copilot, event.data.repository, issueNumber, labels); } } @@ -54,6 +56,7 @@ class GitHelper { if (event.provider === 'github') { await gitHubService.changeState(event.copilot, event.data.repository.full_name, issue.number, 'open'); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); await gitlabService.changeState(event.copilot, event.data.repository, issue.number, 'reopen'); } } @@ -68,6 +71,7 @@ class GitHelper { if (event.provider === 'github') { return await gitHubService.getUsernameById(event.copilot, assigneeUserId); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); return await gitlabService.getUsernameById(event.copilot, assigneeUserId); } return null; @@ -84,6 +88,7 @@ class GitHelper { if (event.provider === 'github') { await gitHubService.removeAssign(event.copilot, event.data.repository.full_name, issueNumber, assigneeUsername); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); await gitlabService.removeAssign(event.copilot, event.data.repository, issueNumber, assigneeUserId); } } @@ -98,6 +103,7 @@ class GitHelper { if (event.provider === 'github') { await gitHubService.updateIssue(event.copilot, event.data.repository.full_name, issueNumber, newTitle); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); await gitlabService.updateIssue(event.copilot, event.data.repository, issueNumber, newTitle); } } @@ -112,6 +118,7 @@ class GitHelper { if (event.provider === 'github') { await gitHubService.assignUser(event.copilot, event.data.repository.full_name, issueNumber, assignedUser); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); const userId = await gitlabService.getUserIdByLogin(event.copilot, assignedUser); await gitlabService.assignUser(event.copilot, event.data.repository, issueNumber, userId); } @@ -131,6 +138,7 @@ class GitHelper { await gitHubService.markIssueAsPaid(event.copilot, event.data.repository.full_name, issueNumber, challengeUUID, existLabels, winner, createCopilotPayments); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); await gitlabService.markIssueAsPaid(event.copilot, event.data.repository, issueNumber, challengeUUID, existLabels, winner, createCopilotPayments); } else if (event.provider === 'azure') { @@ -139,7 +147,7 @@ class GitHelper { } /** - * Retruns repository full url + * Returns repository full url * @param {Object} event the event * @returns {String} the repository full url */ @@ -162,6 +170,7 @@ class GitHelper { if (event.provider === 'github') { return await gitHubService.getUserIdByLogin(event.copilot, assignee); } else if (event.provider === 'gitlab') { + const gitlabService = await GitlabService.create(event.copilot); return gitlabService.getUserIdByLogin(event.copilot, assignee); } return null; From b2b5960af39046898758800875188b71b8ea4fb6 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Thu, 14 Sep 2023 00:30:10 +0530 Subject: [PATCH 18/28] feat: tweak patch-generation and submission logic for MR webhook --- models/CopilotPayment.js | 13 ++ models/GithubUserMapping.js | 8 + models/GitlabUserMapping.js | 8 + models/Issue.js | 21 ++ models/Project.js | 17 ++ models/ProjectChallengeMapping.js | 7 + models/Repository.js | 10 + models/User.js | 15 ++ models/index.js | 9 +- package-lock.json | 371 +++++++++++++++++++++++++----- package.json | 2 + services/GitlabService.js | 17 +- services/PrivateForkService.js | 18 +- services/PullRequestService.js | 81 +++++-- utils/db-helper.js | 78 ++++++- utils/topcoder-api-helper.js | 45 +++- 16 files changed, 621 insertions(+), 99 deletions(-) diff --git a/models/CopilotPayment.js b/models/CopilotPayment.js index 46c8674..92b127f 100644 --- a/models/CopilotPayment.js +++ b/models/CopilotPayment.js @@ -14,6 +14,19 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} CopilotPayment + * @property {String} id The unique identifier for the CopilotPayment entity. + * @property {String} project The project associated with the payment. + * @property {Number} amount The payment amount. + * @property {String} description The description of the payment. + * @property {Number} challengeId The ID of the associated challenge (if applicable). + * @property {String} challengeUUID The UUID of the associated challenge (if applicable). + * @property {String} closed Indicates whether the payment is closed or not (default is 'false'). + * @property {String} username The username of the Copilot receiving the payment. + * @property {String} status The status of the payment. + */ + const schema = new Schema({ id: { type: String, diff --git a/models/GithubUserMapping.js b/models/GithubUserMapping.js index 6cd5d23..56b0cb5 100644 --- a/models/GithubUserMapping.js +++ b/models/GithubUserMapping.js @@ -7,6 +7,14 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} GithubUserMapping + * @property {String} id The unique identifier for the GithubUserMapping entity. + * @property {String} topcoderUsername The Topcoder username associated with the GitHub user. + * @property {String} githubUsername The GitHub username. + * @property {Number} githubUserId The GitHub user's numeric identifier. + */ + const schema = new Schema({ id: { type: String, diff --git a/models/GitlabUserMapping.js b/models/GitlabUserMapping.js index f87f1d9..6377122 100644 --- a/models/GitlabUserMapping.js +++ b/models/GitlabUserMapping.js @@ -7,6 +7,14 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} GitlabUserMapping + * @property {String} id The unique identifier for the GitlabUserMapping entity. + * @property {String} topcoderUsername The Topcoder username associated with the GitLab user. + * @property {String} gitlabUsername The GitLab username. + * @property {Number} gitlabUserId The GitLab user's numeric identifier. + */ + const schema = new Schema({ id: { type: String, diff --git a/models/Issue.js b/models/Issue.js index 79fb016..61ba943 100644 --- a/models/Issue.js +++ b/models/Issue.js @@ -12,6 +12,27 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} Issue + * @property {String} id The id. + * @property {Number} number From the receiver service. + * @property {String} title The title. + * @property {String} body The body. + * @property {Number[]} prizes Prizes extracted from title. + * @property {String} provider Provider (github or gitlab). + * @property {Number} repositoryId Repository ID. + * @property {String} repoUrl Repository URL. + * @property {String} repositoryIdStr Repository ID as a String. + * @property {Array} labels Labels associated with the issue. + * @property {String} assignee Assignee for the issue. + * @property {Date} updatedAt Date when the issue was last updated. + * @property {Number} challengeId Challenge ID from topcoder API. + * @property {String} challengeUUID Challenge UUID. + * @property {String} projectId Project ID. + * @property {String} status Status of the issue. + * @property {Date} assignedAt Date when the issue was assigned (if applicable). + */ + const schema = new Schema({ id: {type: String, hashKey: true, required: true}, // From the receiver service diff --git a/models/Project.js b/models/Project.js index df53b8d..d2d1499 100755 --- a/models/Project.js +++ b/models/Project.js @@ -12,6 +12,23 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} ProjectChallengeMapping + * @property {String} id The id. + * @property {String} title The title. + * @property {Number} tcDirectId The tc direct id. + * @property {String} tags The tags. + * @property {String} rocketChatWebhook The rocket chat webhook. + * @property {String} rocketChatChannelName The rocket chat channel name. + * @property {String} archived The archived. + * @property {String} owner The owner. + * @property {String} secretWebhookKey The secret webhook key. + * @property {String} copilot The copilot. + * @property {Date} updatedAt The updated at. + * @property {String} createCopilotPayments The create copilot payments. + * @property {Boolean} isConnect Is Topcoder connect. + */ + const schema = new Schema({ id: { type: String, diff --git a/models/ProjectChallengeMapping.js b/models/ProjectChallengeMapping.js index 5b4c585..53a25be 100644 --- a/models/ProjectChallengeMapping.js +++ b/models/ProjectChallengeMapping.js @@ -10,6 +10,13 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} ProjectChallengeMapping + * @property {String} id the id + * @property {String} projectId the project id + * @property {String} challengeId the challenge id + */ + const schema = new Schema({ id: { type: String, diff --git a/models/Repository.js b/models/Repository.js index e9a8f1a..ae63fb2 100644 --- a/models/Repository.js +++ b/models/Repository.js @@ -12,6 +12,16 @@ const dynamoose = require('dynamoose'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} Repository + * @property {String} id The unique identifier for the Repository entity. + * @property {String} projectId The project ID associated with the repository. + * @property {String} url The URL of the repository. + * @property {String} archived Indicates whether the repository is archived or not. + * @property {String} repoId The repository ID (if applicable). + * @property {String} registeredWebhookId The ID of the registered webhook (if applicable). + */ + const schema = new Schema({ id: { type: String, diff --git a/models/User.js b/models/User.js index 7237dfe..96cef0a 100755 --- a/models/User.js +++ b/models/User.js @@ -12,6 +12,21 @@ const constants = require('../constants'); const Schema = dynamoose.Schema; +/** + * @typedef {Object} User + * @property {String} id The user's unique identifier. + * @property {Number} userProviderId The user provider's numeric identifier. + * @property {String} userProviderIdStr The user provider's identifier as a string. + * @property {String} username The user's username. + * @property {String} role The user's role, one of the allowed constants.USER_ROLES. + * @property {String} type The user's type, one of the allowed constants.USER_TYPES. + * @property {String} accessToken GitLab token data (if applicable). + * @property {Date} accessTokenExpiration Expiration date of the access token (if applicable). + * @property {String} refreshToken GitLab token refresh token (if applicable). + * @property {String} lockId Lock identifier (if applicable). + * @property {Date} lockExpiration Expiration date of the lock (if applicable). + */ + const schema = new Schema({ id: { type: String, diff --git a/models/index.js b/models/index.js index 4d8dbc1..07f58e2 100644 --- a/models/index.js +++ b/models/index.js @@ -35,16 +35,23 @@ if (process.env.CREATE_DB) { /* eslint-disable global-require */ const models = { + /** @type {import('dynamoose').ModelConstructor} */ Issue: dynamoose.model('Topcoder_X.Issue', require('./Issue')), + /** @type {import('dynamoose').ModelConstructor} */ Project: dynamoose.model('Topcoder_X.Project', require('./Project')), + /** @type {import('dynamoose').ModelConstructor} */ ProjectChallengeMapping: dynamoose.model('Topcoder_X.ProjectChallengeMapping', require('./ProjectChallengeMapping')), + /** @type {import('dynamoose').ModelConstructor} */ User: dynamoose.model('Topcoder_X.User', require('./User')), + /** @type {import('dynamoose').ModelConstructor} */ CopilotPayment: dynamoose.model('Topcoder_X.CopilotPayment', require('./CopilotPayment')), + /** @type {import('dynamoose').ModelConstructor} */ GithubUserMapping: dynamoose.model('Topcoder_X.GithubUserMapping', require('./GithubUserMapping')), + /** @type {import('dynamoose').ModelConstructor} */ GitlabUserMapping: dynamoose.model('Topcoder_X.GitlabUserMapping', require('./GitlabUserMapping')), + /** @type {import('dynamoose').ModelConstructor} */ Repository: dynamoose.model('Topcoder_X.Repository', require('./Repository')) }; /* eslint-enable global-require */ - module.exports = models; diff --git a/package-lock.json b/package-lock.json index 929ac63..e5420b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,12 @@ "dependencies": { "@gitbeaker/rest": "^39.13.0", "@octokit/rest": "^18.9.0", + "archiver": "^6.0.1", "axios": "^0.19.0", "circular-json": "^0.5.7", "config": "^1.30.0", "dynamoose": "^1.11.1", + "form-data": "^4.0.0", "fs-extra": "^7.0.0", "get-parameter-names": "^0.3.0", "global-request-logger": "^0.1.1", @@ -831,6 +833,102 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/archiver": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", + "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "dependencies": { + "archiver-utils": "^4.0.1", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^5.0.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/archiver-utils": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", + "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "dependencies": { + "glob": "^8.0.0", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/archiver-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/are-docs-informative": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", @@ -893,6 +991,11 @@ "node": "*" } }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -932,17 +1035,6 @@ } ] }, - "node_modules/auth0-js/node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/auth0-js/node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -969,19 +1061,6 @@ } } }, - "node_modules/auth0-js/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/auth0-js/node_modules/formidable": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", @@ -1157,6 +1236,11 @@ "is-buffer": "^2.0.2" } }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -1245,8 +1329,7 @@ "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "devOptional": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "node_modules/base64-js": { "version": "1.3.1", @@ -1591,9 +1674,9 @@ } }, "node_modules/combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1621,6 +1704,33 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, + "node_modules/compress-commons": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", + "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^5.0.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/compress-commons/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1721,6 +1831,42 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", + "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/crc32-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3310,6 +3456,11 @@ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -3460,16 +3611,16 @@ } }, "node_modules/form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, "node_modules/formidable": { @@ -3513,8 +3664,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/function-bind": { "version": "1.1.1", @@ -3722,12 +3872,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "engines": { - "node": ">=0.4.0" - } + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/graphemer": { "version": "1.4.0", @@ -4086,7 +4233,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "devOptional": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -4683,6 +4829,17 @@ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, "node_modules/le_node": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/le_node/-/le_node-1.8.0.tgz", @@ -5222,6 +5379,14 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/normalize-url": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.2.0.tgz", @@ -5592,8 +5757,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/progress": { "version": "1.1.8", @@ -5700,6 +5864,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -5786,7 +5955,6 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5797,6 +5965,33 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readline2": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", @@ -5904,6 +6099,20 @@ "request": "^2.34" } }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", @@ -6308,11 +6517,19 @@ "node": ">=0.10.0" } }, + "node_modules/streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -6417,6 +6634,19 @@ "resolved": "https://registry.npmjs.org/superagent-promise/-/superagent-promise-1.1.0.tgz", "integrity": "sha1-uvIti73UOamwfdEPjAj1T+JQNTM=" }, + "node_modules/superagent/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/superagent/node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -6587,6 +6817,16 @@ "node": ">=0.8.0" } }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tc-core-library-js": { "version": "2.4.1", "resolved": "git+ssh://git@github.com/appirio-tech/tc-core-library-js.git#f45352974dafe5a10c86fc50bdd59ef399b50c65", @@ -6627,17 +6867,6 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, - "node_modules/tc-core-library-js/node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/tc-core-library-js/node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7229,6 +7458,32 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zip-stream": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", + "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "dependencies": { + "archiver-utils": "^4.0.1", + "compress-commons": "^5.0.1", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/zip-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } } } } diff --git a/package.json b/package.json index 5d74f99..eda15c3 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,12 @@ "dependencies": { "@gitbeaker/rest": "^39.13.0", "@octokit/rest": "^18.9.0", + "archiver": "^6.0.1", "axios": "^0.19.0", "circular-json": "^0.5.7", "config": "^1.30.0", "dynamoose": "^1.11.1", + "form-data": "^4.0.0", "fs-extra": "^7.0.0", "get-parameter-names": "^0.3.0", "global-request-logger": "^0.1.1", diff --git a/services/GitlabService.js b/services/GitlabService.js index 8dd94db..9932da7 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -73,7 +73,7 @@ class GitlabService { /** @type {User} */ #user = null; - /** @type {Gitlab} */ + /** @type {import('@gitbeaker/rest').Gitlab} */ #gitlab = null; constructor(user) { @@ -84,6 +84,15 @@ class GitlabService { this.#user = user; } + /** + * Get the full URL for a Gitlab repository from its full name. + * @param {String} repoFullName Repo full name + * @returns {String} + */ + static getRepoUrl(repoFullName) { + return `${config.GITLAB_API_BASE_URL}/${repoFullName}`; + } + /** * Helper method for initializing a GitlabService instance with an active * access token. @@ -478,8 +487,8 @@ class GitlabService { acc += `deleted file mode ${file.a_mode}\n`; } if (file.diff && file.diff !== '') { - acc += `--- a/${file.new_file ? '/dev/null' : file.old_path}\n`; - acc += `+++ b/${file.deleted_file ? '/dev/null' : file.new_path}\n`; + acc += `--- ${file.new_file ? '/dev/null' : `a/${file.old_path}`}\n`; + acc += `+++ ${file.deleted_file ? '/dev/null' : `b/${file.new_path}`}\n`; acc += file.diff; } else if (file.renamed_file) { acc += 'similarity index 100%\n'; @@ -488,7 +497,9 @@ class GitlabService { } return acc; }, ''); + console.log(`PATCH FILE STARTS::${mergeRequest.web_url}`); console.log(patchFile); + console.log(`PATCH FILE ENDS::${mergeRequest.web_url}`); return patchFile; } diff --git a/services/PrivateForkService.js b/services/PrivateForkService.js index 4d24411..8c25ff1 100644 --- a/services/PrivateForkService.js +++ b/services/PrivateForkService.js @@ -10,7 +10,6 @@ const errors = require('../utils/errors'); const GitlabService = require('../services/GitlabService'); const {GITLAB_ACCESS_LEVELS, USER_ROLES, USER_TYPES} = require('../constants'); -const ProjectChallengeMapping = models.ProjectChallengeMapping; const Project = models.Project; const User = models.User; const GitlabUserMapping = models.GitlabUserMapping; @@ -30,24 +29,13 @@ async function process(payload) { logger.debug(`${logPrefix}: Member ID: ${memberId}`); logger.debug(`${logPrefix}: Member Handle: ${memberHandle}`); // Check if there are projects mapped to the challenge - const filterValues = {}; - const filter = { - FilterExpression: '#challengeId = :challengeId', - ExpressionAttributeNames: { - '#challengeId': 'challengeId' - }, - ExpressionAttributeValues: { - ':challengeId': challengeId - } - }; - const projectChallengeMapping = await dbHelper.scan(ProjectChallengeMapping, filter, filterValues); - if (projectChallengeMapping.length === 0) { + const projectId = await dbHelper.queryProjectIdByChallengeId(challengeId); + if (!projectId) { logger.info(`${logPrefix} ProjectChallengeMapping not found for challengeId: ${challengeId}`); return; } - logger.debug(`${logPrefix} ProjectChallengeMapping: ${JSON.stringify(projectChallengeMapping)}`); + logger.debug(`${logPrefix} TCX ProjectId: ${projectId}`); // Get Project - const projectId = projectChallengeMapping[0].projectId; const project = await dbHelper.getById(Project, projectId); if (!project) { logger.info(`${logPrefix} Project not found for projectId: ${projectId}`); diff --git a/services/PullRequestService.js b/services/PullRequestService.js index 5cc37c9..28c1816 100644 --- a/services/PullRequestService.js +++ b/services/PullRequestService.js @@ -3,13 +3,24 @@ const _ = require('lodash'); const Joi = require('joi'); const uuid = require('uuid').v4; +const archiver = require('archiver'); const models = require('../models'); const dbHelper = require('../utils/db-helper'); const logger = require('../utils/logger'); const GitlabService = require('../services/GitlabService'); +const TopcoderApiHelper = require('../utils/topcoder-api-helper'); const GitlabUserMapping = models.GitlabUserMapping; +/** + * Normalizes a string to be used as a file name. + * @param {String} fileName File name to normalize + * @returns {String} Normalized file name + */ +function normalizeFileName(fileName) { + return fileName.replace(/[^a-zA-Z0-9_\-.]/g, '_'); +} + /** * Handles a pull request creation event. * @param {Object} payload The event payload. @@ -59,44 +70,53 @@ async function process(payload) { return; } logger.debug(`${logPrefix} Project: ${JSON.stringify(project)}`); - // 4. Find all repositories corresponding to the TCX project + // 4. Find the challenge ID for the TCX project + const challengeId = await dbHelper.queryChallengeIdByProjectId(project.id); + if (!challengeId) { + logger.info(`${logPrefix} ProjectChallengeMapping not found for projectId: ${project.id}`); + return; + } + logger.debug(`${logPrefix} Challenge ID: ${challengeId}`); + // 5. Find all repositories corresponding to the TCX project const repositories = await dbHelper.queryAllRepositoriesByProjectId(project.id); if (!repositories || repositories.length === 0) { logger.info(`${logPrefix} Repositories not found for projectId: ${project.id}`); return; } logger.debug(`${logPrefix} Repositories: ${JSON.stringify(repositories)}`); - // 5. Get co-pilot's GitlabUserMapping + // 6. Get co-pilot's GitlabUserMapping const copilot = await dbHelper.queryOneUserMappingByTCUsername(GitlabUserMapping, project.copilot); if (!copilot) { logger.info(`${logPrefix} GitlabUserMapping not found for copilot: ${project.copilot}`); return; } logger.debug(`${logPrefix} GitlabUserMapping[Copilot]: ${JSON.stringify(copilot)}`); - // 6. Get co-pilot's Gitlab user + // 7. Get co-pilot's Gitlab user const copilotGitlabUser = await dbHelper.queryOneUserByType(models.User, copilot.gitlabUsername, 'gitlab'); if (!copilotGitlabUser) { logger.info(`${logPrefix} GitlabUser not found for copilot: ${project.copilot}`); return; } logger.debug(`${logPrefix} GitlabUser[Copilot]: ${JSON.stringify(copilotGitlabUser)}`); - // 7. For each project, get the repositories - const gitRepositories = await Promise.all(repositories.map((repo) => GitlabService.getRepository(copilotGitlabUser, repo.url))); + // 8. Init the Gitlab service for co-pilot + const copilotGitlabService = await GitlabService.create(copilotGitlabUser); + // 9. For each project, get the repositories + const gitRepositories = await Promise.all(repositories.map((repo) => copilotGitlabService.getRepository(repo.url))); if (!gitRepositories || gitRepositories.length === 0) { logger.info(`${logPrefix} Git repositories not found for repositories: ${JSON.stringify(repositories)}`); return; } logger.debug(`${logPrefix} Git repositories: ${JSON.stringify(gitRepositories)}`); - // 8. For each repository, get the merge requests + // 10. For each repository, get the merge requests const mergeRequests = await Promise.all( - gitRepositories.map((repo) => GitlabService.getOpenMergeRequestsByUser(copilotGitlabUser, repo, submitter.gitlabUserId)) + gitRepositories.map((repo) => copilotGitlabService.getOpenMergeRequestsByUser(repo, submitter.gitlabUserId)) ); if (!mergeRequests || mergeRequests.length === 0) { logger.info(`${logPrefix} Merge requests not found for repositories: ${JSON.stringify(gitRepositories)}`); return; } logger.debug(`${logPrefix} Merge requests: ${JSON.stringify(mergeRequests)}`); - // 9. Ensure that there exists a merge request by the same member as the pull request for each project (if not, return) + // 11. Ensure that there exists a merge request by the same member as the pull request for each project (if not, return) // eslint-disable-next-line no-restricted-syntax for (let i = 0; i < mergeRequests.length; i += 1) { const mr = mergeRequests[i]; @@ -105,21 +125,54 @@ async function process(payload) { return; } } - // 10. Get the latest merge request for each project + // 12. Get the latest merge request for each project const latestMergeRequests = mergeRequests.map((mrs) => _.maxBy(mrs, (mr) => new Date(mr.created_at).getTime())); logger.debug(`${logPrefix} Latest merge requests: ${JSON.stringify(latestMergeRequests)}`); - // 11. Create patch files for each merge request + // 13. Create patch files for each merge request const patches = await Promise.all( - latestMergeRequests.map((mr) => GitlabService.getMergeRequestDiffPatches(copilotGitlabUser, mr)) + latestMergeRequests.map((mr) => copilotGitlabService.getMergeRequestDiffPatches(mr)) ); if (!patches || patches.length !== latestMergeRequests.length) { logger.info(`${logPrefix} Patches not found for merge requests.`); return; } logger.debug(`${logPrefix} Patches: ${JSON.stringify(patches)}`); - // 11. Get the topcoder M2M token - // 10. Create a zip file containing all patch files - // 11. Use the submission API to submit the zip file + // 14. Create a zip file containing all patch files + logger.debug(`${logPrefix} Creating zip file...`); + const zipStream = archiver('zip'); + const zipBufferPromise = new Promise((resolve, reject) => { + const buffers = []; + zipStream.on('data', (data) => { + buffers.push(data); + }); + zipStream.on('end', () => { + resolve(Buffer.concat(buffers)); + }); + zipStream.on('error', reject); + }); + patches.forEach((patch) => { + const buffer = Buffer.from(patch); + zipStream.append(buffer, {name: `${normalizeFileName(repoFullName)}.patch`}); + }); + await zipStream.finalize(); + const zipBuffer = await zipBufferPromise; + logger.debug(`${logPrefix} Zip file size: ${zipBuffer.length}`); + // 15. Get the Topcoder user's member ID + const memberId = await TopcoderApiHelper.getTopcoderMemberId(submitter.topcoderUsername); + if (!memberId) { + logger.info(`${logPrefix} Member ID not found for topcoderUsername: ${submitter.topcoderUsername}`); + return; + } + logger.debug(`${logPrefix} Member ID: ${memberId}`); + // 16. Use the submission API to submit the zip file + logger.debug(`${logPrefix} Submitting the zip file...`); + const submission = await TopcoderApiHelper.createSubmission( + challengeId, + memberId, + zipBuffer, + `${correlationId}.zip`, + ); + logger.debug(`${logPrefix} Submission: ${JSON.stringify(submission.data)}`); } process.schema = Joi.object().keys({ diff --git a/utils/db-helper.js b/utils/db-helper.js index 873fca6..2c707b0 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -11,6 +11,24 @@ const logger = require('./logger'); * @version 1.0 */ +/** + * @typedef {Object} GitlabUserMapping + * @property {String} id the id + * @property {Number} gitlabUserId the gitlab user id + * @property {String} topcoderUsername the topcoder username + * @property {String} gitlabUsername the gitlab username + */ + +/** + * @typedef {Object} Repository + * @property {String} id the id + * @property {String} projectId the project id + * @property {String} url the repository url + * @property {String} archived the archived flag + * @property {String} repoId the repository id + * @property {String} registeredWebhookId the registered webhook id + */ + /** * Get Data by model id * @param {Object} model The dynamoose model to query @@ -150,7 +168,7 @@ async function queryOneUserByTypeAndRole(model, username, type, role) { /** * Query project by repository url * @param {String} repoUrl the repo url - * @returns {Promise} + * @returns {Promise} */ async function queryOneProjectByRepositoryLink(repoUrl) { const projectId = await new Promise((resolve, reject) => { @@ -187,7 +205,7 @@ async function queryOneProjectByRepositoryLink(repoUrl) { * Get single data by query parameters * @param {Object} model The dynamoose model to query * @param {String} tcusername The tc username - * @returns {Promise} + * @returns {Promise} */ async function queryOneUserMappingByTCUsername(model, tcusername) { return await new Promise((resolve, reject) => { @@ -267,7 +285,7 @@ async function queryOneUserMappingByGithubUserId(model, userId) { * Get single data by query parameters * @param {Object} model The dynamoose model to query * @param {Number} userId The The user id - * @returns {Promise} + * @returns {Promise} */ async function queryOneUserMappingByGitlabUserId(model, userId) { return await new Promise((resolve, reject) => { @@ -490,6 +508,56 @@ async function releaseLockOnUser(id, lockId) { return user; } +/** + * Find the TC Challenge ID for a given TCX project ID + * @param {String} projectId Project ID + * @returns {Promise} Challenge ID + */ +async function queryChallengeIdByProjectId(projectId) { + const filter = { + FilterExpression: '#projectId = :projectId', + ExpressionAttributeNames: { + '#projectId': 'projectId' + }, + ExpressionAttributeValues: { + ':projectId': projectId + } + }; + return new Promise((resolve, reject) => { + models.ProjectChallengeMapping.scan(filter, (err, result) => { + if (err) { + return reject(err); + } + return resolve(result.count === 0 ? null : result[0].challengeId); + }); + }); +} + +/** + * Find the TCX Project ID for a given TC Challenge ID + * @param {String} challengeId Challenge ID + * @returns {Promise} Project ID + */ +async function queryProjectIdByChallengeId(challengeId) { + const filter = { + FilterExpression: '#challengeId = :challengeId', + ExpressionAttributeNames: { + '#challengeId': 'challengeId' + }, + ExpressionAttributeValues: { + ':challengeId': challengeId + } + }; + return new Promise((resolve, reject) => { + models.ProjectChallengeMapping.scan(filter, (err, result) => { + if (err) { + return reject(err); + } + return resolve(result.count === 0 ? null : result[0].projectId); + }); + }); +} + module.exports = { getById, scan, @@ -512,5 +580,7 @@ module.exports = { removeCopilotPayment, removeIssue, acquireLockOnUser, - releaseLockOnUser + releaseLockOnUser, + queryChallengeIdByProjectId, + queryProjectIdByChallengeId }; diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index de63381..1ba3092 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -13,9 +13,10 @@ 'use strict'; const config = require('config'); -const axios = require('axios'); +const axios = require('axios').default; const _ = require('lodash'); const circularJSON = require('circular-json'); +const FormData = require('form-data'); const m2mAuth = require('tc-core-library-js').auth.m2m; @@ -465,8 +466,43 @@ async function getProjectByDirectId(id, directId) { }); } -async function createSubmission(challengeId, submissionFileStream, submissionFileName, submissionType) { - // TODO: Implement submission creation +/** + * Create a new submission. + * @param {String} challengeId Challenge ID + * @param {Number} memberId Member ID + * @param {Buffer} submissionFile Submission file + * @param {String} submissionFileName Submission file name + */ +async function createSubmission(challengeId, memberId, submissionFile, submissionFileName) { + try { + const formData = new FormData(); + formData.append('submission', submissionFile, { + filename: submissionFileName, + contentType: 'application/zip', + knownLength: submissionFile.length + }); + formData.append('type', 'Contest Submission'); + formData.append('memberId', memberId); + formData.append('challengeId', challengeId); + const apiKey = await getM2Mtoken(); + const res = await axios.post(`${config.TC_API_URL}/submissions`, formData, { + headers: { + authorization: `Bearer ${apiKey}`, + accept: 'application/json', + ...formData.getHeaders() + } + }); + return res; + } catch (error) { + logger.error('createSubmission ERROR.'); + if (error.isAxiosError) { + logger.error(`Request: ${JSON.stringify(error.config)}`); + logger.error(`Response Data: ${JSON.stringify(error.response.data)}`); + } else { + logger.error(`${error.message}`, error); + } + throw errors.convertTopcoderApiError(error, 'Failed to create submission.'); + } } module.exports = { @@ -485,5 +521,6 @@ module.exports = { cancelPrivateContent, assignUserAsRegistrant, removeResourceToChallenge, - getProjectByDirectId + getProjectByDirectId, + createSubmission }; From 422051218645c6cb201d4d53222cc873cacae70f Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Fri, 15 Sep 2023 10:51:02 +0530 Subject: [PATCH 19/28] fix: additional bug fixes for Gitlab service refactor --- services/GitlabService.js | 5 ++++- services/IssueService.js | 15 +++++++-------- services/UserService.js | 15 +++++---------- utils/git-helper.js | 20 ++++++++++---------- utils/kafka-consumer.js | 1 - utils/notification.js | 2 +- utils/topcoder-api-helper.js | 4 ++-- 7 files changed, 29 insertions(+), 33 deletions(-) diff --git a/services/GitlabService.js b/services/GitlabService.js index 9932da7..dccb512 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -159,7 +159,10 @@ class GitlabService { } finally { if (lockedUser) { logger.debug(`[Lock ID: ${lockId}] Releasing lock on user ${this.#user.username}.`); - this.#user = await dbHelper.releaseLockOnUser(this.#user.id, lockId); + const newUser = await dbHelper.releaseLockOnUser(this.#user.id, lockId); + // Not assigning directly because the old object sometimes has properties + // that are not in the new one + _.assign(this.#user, newUser); } } } diff --git a/services/IssueService.js b/services/IssueService.js index 0d24826..a845f6c 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -20,9 +20,9 @@ const models = require('../models'); const dbHelper = require('../utils/db-helper'); const helper = require('../utils/helper'); const gitHelper = require('../utils/git-helper'); +const constants = require('../constants'); const userService = require('./UserService'); const eventService = require('./EventService'); -const constants = require('../constants'); // A variable to store issue creation lock to prevent duplicate creation process. @@ -80,7 +80,7 @@ async function ensureChallengeExists(event, issue, create = true) { logger.debugWithContext('dbIssue is PENDING', event, issue); throw errors.internalDependencyError(`Challenge for the updated issue ${issue.number} is creating, rescheduling this event`); } - const hasOpenForPickupLabel = _(issue.labels).includes(config.OPEN_FOR_PICKUP_ISSUE_LABEL); + const hasOpenForPickupLabel = _.includes(issue.labels, config.OPEN_FOR_PICKUP_ISSUE_LABEL); if (dbIssue && dbIssue.status === constants.ISSUE_STATUS.CHALLENGE_CREATION_FAILED && hasOpenForPickupLabel) { // remove issue from db await dbHelper.removeIssue(models.Issue, issue.repositoryId, issue.number, issue.provider); @@ -437,7 +437,7 @@ async function handleIssueClose(event, issue) { // eslint-disable-line if (closeChallenge) { logger.debugWithContext(`The associated challenge ${dbIssue.challengeUUID} is being scheduled for cancellation since no payment will be given`, - event, issue); + event, issue); await dbHelper.update(models.Issue, dbIssue.id, { status: constants.ISSUE_STATUS.CHALLENGE_CANCELLED, updatedAt: new Date() @@ -500,7 +500,7 @@ async function handleIssueClose(event, issue) { // eslint-disable-line if (createCopilotPayments) { logger.debugWithContext('Setting copilot payment'); - const updateBody = { + const _updateBody = { prizeSets: [{ type: 'placement', prizes: _.map(issue.prizes, (prize) => ({type: 'USD', value: prize})) @@ -511,7 +511,7 @@ async function handleIssueClose(event, issue) { // eslint-disable-line } ] }; - await topcoderApiHelper.updateChallenge(dbIssue.challengeUUID, updateBody); + await topcoderApiHelper.updateChallenge(dbIssue.challengeUUID, _updateBody); } else { logger.debugWithContext('Create copilot payments is unchecked on the Topcoder-X project setup, so skipping', event, issue); } @@ -575,7 +575,6 @@ async function handleIssueClose(event, issue) { // eslint-disable-line } } - /** * handles the issue create event * @param {Object} event the event @@ -636,7 +635,7 @@ async function handleIssueCreate(event, issue, forceAssign = false) { issue.challengeUUID = await topcoderApiHelper.createChallenge({ name: issue.title, projectId, - tags: !!project.tags ? project.tags.split(',') : [], + tags: project.tags ? project.tags.split(',') : [], detailedRequirements: issue.body, prizes: issue.prizes }); @@ -676,7 +675,7 @@ async function handleIssueCreate(event, issue, forceAssign = false) { } delete issueCreationLock[creationLockKey]; } catch (err) { - logger.error(`Comment creation failure: ${err}`); + logger.error(`Comment creation failure: ${err}`, err); delete issueCreationLock[creationLockKey]; logger.debugWithContext(`new challenge created with id ${issue.challengeUUID} for issue ${issue.number}`, event, issue); } diff --git a/services/UserService.js b/services/UserService.js index 71379e7..e2f0260 100755 --- a/services/UserService.js +++ b/services/UserService.js @@ -25,23 +25,21 @@ const models = require('../models'); */ async function getTCUserName(provider, gitUser) { Joi.attempt({provider, gitUser}, getTCUserName.schema); - const criteria = {}; if (_.isNumber(gitUser) || v.isUUID(gitUser)) { if (provider === 'github') { return await dbHelper.queryOneUserMappingByGithubUserId(models.GithubUserMapping, gitUser); } else if (provider === 'gitlab') { return await dbHelper.queryOneUserMappingByGitlabUserId(models.GitlabUserMapping, gitUser); } - } else if (_.isString(gitUser) || v.isEmail(gitUser)) { + } + if (_.isString(gitUser) || v.isEmail(gitUser)) { if (provider === 'github') { return await dbHelper.queryOneUserMappingByGithubUsername(models.GithubUserMapping, gitUser); } else if (provider === 'gitlab') { return await dbHelper.queryOneUserMappingByGitlabUsername(models.GitlabUserMapping, gitUser); } } - if (_.isEmpty(criteria)) { - throw new Error('Can\'t find the TCUserName. Invalid gitUser.'); - } + throw new Error('Can\'t find the TCUserName. Invalid gitUser.'); } getTCUserName.schema = { @@ -54,7 +52,7 @@ getTCUserName.schema = { * gets the access token of repository's copilot/owner captured by Topcoder x tool * @param {String} provider the repo provider * @param {String} repoFullName the full name of repository - * @returns {String} the copilot/owner if exists + * @returns {Promise} the copilot/owner if exists */ async function getRepositoryCopilotOrOwner(provider, repoFullName) { Joi.attempt({provider, repoFullName}, getRepositoryCopilotOrOwner.schema); @@ -96,10 +94,7 @@ async function getRepositoryCopilotOrOwner(provider, repoFullName) { } return { - accessToken: user.accessToken, - accessTokenExpiration: user.accessTokenExpiration, - refreshToken: user.refreshToken, - userProviderId: user.userProviderId, + ...user, topcoderUsername: userMapping.topcoderUsername }; } diff --git a/utils/git-helper.js b/utils/git-helper.js index 2c90631..36e1e79 100644 --- a/utils/git-helper.js +++ b/utils/git-helper.js @@ -28,7 +28,7 @@ class GitHelper { await gitHubService.createComment(event.copilot, event.data.repository.full_name, issueNumber, comment); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - await gitlabService.createComment(event.copilot, event.data.repository, issueNumber, comment); + await gitlabService.createComment(event.data.repository, issueNumber, comment); } } @@ -43,7 +43,7 @@ class GitHelper { await gitHubService.addLabels(event.copilot, event.data.repository.full_name, issueNumber, labels); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - await gitlabService.addLabels(event.copilot, event.data.repository, issueNumber, labels); + await gitlabService.addLabels(event.data.repository, issueNumber, labels); } } @@ -57,7 +57,7 @@ class GitHelper { await gitHubService.changeState(event.copilot, event.data.repository.full_name, issue.number, 'open'); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - await gitlabService.changeState(event.copilot, event.data.repository, issue.number, 'reopen'); + await gitlabService.changeState(event.data.repository, issue.number, 'reopen'); } } @@ -65,14 +65,14 @@ class GitHelper { * Gets the user name by user id * @param {Object} event the event * @param {Number} assigneeUserId the user id - * @returns {String} the username + * @returns {Promise} the username */ async getUsernameById(event, assigneeUserId) { if (event.provider === 'github') { return await gitHubService.getUsernameById(event.copilot, assigneeUserId); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - return await gitlabService.getUsernameById(event.copilot, assigneeUserId); + return await gitlabService.getUsernameById(assigneeUserId); } return null; } @@ -89,7 +89,7 @@ class GitHelper { await gitHubService.removeAssign(event.copilot, event.data.repository.full_name, issueNumber, assigneeUsername); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - await gitlabService.removeAssign(event.copilot, event.data.repository, issueNumber, assigneeUserId); + await gitlabService.removeAssign(event.data.repository, issueNumber, assigneeUserId); } } @@ -104,7 +104,7 @@ class GitHelper { await gitHubService.updateIssue(event.copilot, event.data.repository.full_name, issueNumber, newTitle); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - await gitlabService.updateIssue(event.copilot, event.data.repository, issueNumber, newTitle); + await gitlabService.updateIssue(event.data.repository, issueNumber, newTitle); } } @@ -120,7 +120,7 @@ class GitHelper { } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); const userId = await gitlabService.getUserIdByLogin(event.copilot, assignedUser); - await gitlabService.assignUser(event.copilot, event.data.repository, issueNumber, userId); + await gitlabService.assignUser(event.data.repository, issueNumber, userId); } } @@ -139,7 +139,7 @@ class GitHelper { createCopilotPayments); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - await gitlabService.markIssueAsPaid(event.copilot, event.data.repository, issueNumber, challengeUUID, existLabels, winner, + await gitlabService.markIssueAsPaid(event.data.repository, issueNumber, challengeUUID, existLabels, winner, createCopilotPayments); } else if (event.provider === 'azure') { await azureService.markIssueAsPaid(event.copilot, event.data.repository.full_name, issueNumber, challengeUUID, existLabels); @@ -171,7 +171,7 @@ class GitHelper { return await gitHubService.getUserIdByLogin(event.copilot, assignee); } else if (event.provider === 'gitlab') { const gitlabService = await GitlabService.create(event.copilot); - return gitlabService.getUserIdByLogin(event.copilot, assignee); + return gitlabService.getUserIdByLogin(assignee); } return null; } diff --git a/utils/kafka-consumer.js b/utils/kafka-consumer.js index fe061bc..4b76f05 100644 --- a/utils/kafka-consumer.js +++ b/utils/kafka-consumer.js @@ -46,7 +46,6 @@ function tcxMessageHandler(messageSet, topic) { // The event should be a JSON object event = parsePayload(event); try { - console.log(event); event.message.value.payload.value = JSON.parse(event.message.value.payload.value); } catch (e) { logger.error('Invalid message payload', e); diff --git a/utils/notification.js b/utils/notification.js index f294275..de788a1 100644 --- a/utils/notification.js +++ b/utils/notification.js @@ -10,7 +10,6 @@ const config = require('config'); const kafkaSender = require('./kafka-sender'); -const topcoderApiHelper = require('./topcoder-api-helper'); const logger = require('./logger'); const notification = {}; @@ -31,6 +30,7 @@ function getContent(repoPath) { } notification.sendTokenExpiredAlert = async function sendTokenExpiredAlert(copilotHandle, repoPath, provider) { + const topcoderApiHelper = await import('./topcoder-api-helper'); const copilotId = await topcoderApiHelper.getTopcoderMemberId(copilotHandle); const notificationConfigs = config.MAIL_NOTICIATION; const content = getContent(repoPath); diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index 1ba3092..58b05ca 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -62,7 +62,7 @@ async function createProject(projectName) { /** * Create a new challenge. * @param {Object} challenge the challenge to create - * @returns {Number} the created challenge id + * @returns {Promise} the created challenge id */ async function createChallenge(challenge) { const apiKey = await getM2Mtoken(); @@ -268,7 +268,7 @@ async function getProjectBillingAccountId(id) { /** * gets the topcoder user id from handle * @param {String} handle the topcoder handle - * @returns {Number} the user id + * @returns {Promise} the user id */ async function getTopcoderMemberId(handle) { try { From 2376e7cae3f0a7da802fc06080d28ad945747bdd Mon Sep 17 00:00:00 2001 From: Gunasekar-K Date: Thu, 12 Oct 2023 18:44:37 +0530 Subject: [PATCH 20/28] Update Dockerfile --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 42a33a8..5cf979d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -6,4 +6,4 @@ COPY package.json package-lock.json ./ RUN npm ci --silent --legacy-peer-deps COPY . . -CMD npm start +CMD node ./index.js From 48ade0ad4bd5bc070cc1dccda116cb64587f6ac5 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Wed, 18 Oct 2023 16:50:04 +0530 Subject: [PATCH 21/28] feat: use v5 endpoint for tags --- models/Project.js | 28 ++++++++++++++++++++++++++-- services/ChallengeService.js | 9 +++++++-- services/CopilotPaymentService.js | 2 +- services/IssueService.js | 2 +- utils/db-helper.js | 1 + 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/models/Project.js b/models/Project.js index d2d1499..2dbf375 100755 --- a/models/Project.js +++ b/models/Project.js @@ -41,9 +41,33 @@ const schema = new Schema({ required: true }, tags: { - type: String, + type: 'list', + list: [{ + type: 'map', + map: { + id: {type: String, required: true}, + name: {type: String, required: true} + } + }], required: true, - default: '' + default: [], + fromDynamo(value) { + if (value.S) { + return value.S; + } + if (value.L) { + return value.L.map((item) => { + if (item.M && item.M.name && item.M.id) { + return { + id: item.M.id.S, + name: item.M.name.S + }; + } + return null; + }); + } + return []; + } }, rocketChatWebhook: {type: String, required: false}, rocketChatChannelName: {type: String, required: false}, diff --git a/services/ChallengeService.js b/services/ChallengeService.js index ae4dd22..93fca2e 100644 --- a/services/ChallengeService.js +++ b/services/ChallengeService.js @@ -20,7 +20,7 @@ const dbHelper = require('../utils/db-helper'); * @param {Object} event the event */ async function handleChallengeTagsUpdate(event) { - const tags = event.data.tags.split(','); + const tags = event.data.tags.map((tag) => tag.name); await Promise.all( event.data.challengeUUIDsList.map(async (challengeUUIDs) => { if (_.isString(challengeUUIDs)) { // repoUrl @@ -54,7 +54,12 @@ process.schema = Joi.object().keys({ challengeUUIDsList: Joi.array().items( Joi.alternatives().try(Joi.string(), Joi.array().items(Joi.string())) ).required(), - tags: Joi.string().required() + tags: Joi.array().items( + Joi.object().keys({ + id: Joi.string().required(), + name: Joi.string().required() + }) + ).required() }).required(), retryCount: Joi.number().integer().default(0).optional() }); diff --git a/services/CopilotPaymentService.js b/services/CopilotPaymentService.js index f828244..74f4525 100644 --- a/services/CopilotPaymentService.js +++ b/services/CopilotPaymentService.js @@ -194,7 +194,7 @@ async function handlePaymentAdd(event, payment) { const newChallenge = { name: challengeTitle, projectId: project.tcDirectId, - tags: !!project.tags ? project.tags.split(',') : [], + tags: project.tags ? project.tags.map((tag) => tag.name) : [], detailedRequirements: challengeRequirements, prizes: [payment.amount], reviewType: 'INTERNAL' diff --git a/services/IssueService.js b/services/IssueService.js index a845f6c..9a427b6 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -635,7 +635,7 @@ async function handleIssueCreate(event, issue, forceAssign = false) { issue.challengeUUID = await topcoderApiHelper.createChallenge({ name: issue.title, projectId, - tags: project.tags ? project.tags.split(',') : [], + tags: project.tags ? project.tags.map((tag) => tag.name) : [], detailedRequirements: issue.body, prizes: issue.prizes }); diff --git a/utils/db-helper.js b/utils/db-helper.js index 2c707b0..a01bde2 100644 --- a/utils/db-helper.js +++ b/utils/db-helper.js @@ -490,6 +490,7 @@ async function acquireLockOnUser(userId, lockId, ttl) { } }); } + /** * Release lock on user * @param {String} id ID of the user From f9a23431961b3347fe07516ad7905549dc4e9a35 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Thu, 16 Nov 2023 00:04:24 +0530 Subject: [PATCH 22/28] feat: apply skillsets when a challenge is created --- config/default.js | 3 ++- models/Project.js | 2 +- services/CopilotPaymentService.js | 3 +++ services/IssueService.js | 3 +++ utils/logger.js | 2 +- utils/topcoder-api-helper.js | 38 ++++++++++++++++++++++++++++++- 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/config/default.js b/config/default.js index d62967a..e7290c8 100644 --- a/config/default.js +++ b/config/default.js @@ -68,7 +68,7 @@ module.exports = { GRANT_TYPE: 'client_credentials', // used as base to construct various URLs - WEBSITE_SECURE: process.env.WEBSITE_SECURE || 'https://topcoderx.topcoder-dev.com/', + WEBSITE_SECURE: process.env.WEBSITE_SECURE || 'http://topcoderx.topcoder-dev.com/', ROLE_ID_COPILOT: process.env.ROLE_ID_COPILOT || 'cfe12b3f-2a24-4639-9d8b-ec86726f76bd', ROLE_ID_ITERATIVE_REVIEWER: process.env.ROLE_ID_ITERATIVE_REVIEWER || 'f6df7212-b9d6-4193-bfb1-b383586fce63', @@ -76,6 +76,7 @@ module.exports = { TYPE_ID_TASK: process.env.TYPE_ID_TASK || 'ecd58c69-238f-43a4-a4bb-d172719b9f31', DEFAULT_TIMELINE_TEMPLATE_ID: process.env.DEFAULT_TIMELINE_TEMPLATE_ID || '53a307ce-b4b3-4d6f-b9a1-3741a58f77e6', DEFAULT_TRACK_ID: process.env.DEFAULT_TRACK_ID || '9b6fc876-f4d9-4ccb-9dfd-419247628825', + WORK_TYPE_ID: process.env.WORK_TYPE_ID || 'b658b280-6c4d-11e5-9d70-22000b2c9aef', GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION: 3600 * 2, GITLAB_REFRESH_TOKEN_BEFORE_EXPIRATION: 300, GITLAB_CLIENT_ID: process.env.GITLAB_CLIENT_ID, diff --git a/models/Project.js b/models/Project.js index 2dbf375..caf4d67 100755 --- a/models/Project.js +++ b/models/Project.js @@ -17,7 +17,7 @@ const Schema = dynamoose.Schema; * @property {String} id The id. * @property {String} title The title. * @property {Number} tcDirectId The tc direct id. - * @property {String} tags The tags. + * @property {Array<{id: string, name: string}>} tags The tags. * @property {String} rocketChatWebhook The rocket chat webhook. * @property {String} rocketChatChannelName The rocket chat channel name. * @property {String} archived The archived. diff --git a/services/CopilotPaymentService.js b/services/CopilotPaymentService.js index 74f4525..944d50e 100644 --- a/services/CopilotPaymentService.js +++ b/services/CopilotPaymentService.js @@ -203,6 +203,9 @@ async function handlePaymentAdd(event, payment) { // Create a new challenge const challengeUUID = await topcoderApiHelper.createChallenge(newChallenge); + // Apply skills to the challenge + await topcoderApiHelper.applySkillsSet(challengeUUID, project.tags); + logger.debug(`updating database payment with new challenge id:${challengeUUID}`); // update db payment diff --git a/services/IssueService.js b/services/IssueService.js index 9a427b6..4986cc6 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -640,6 +640,9 @@ async function handleIssueCreate(event, issue, forceAssign = false) { prizes: issue.prizes }); + // Apply skills to the challenge + await topcoderApiHelper.applySkillsSetToChallenge(issue.challengeUUID, project.tags); + // Save // update db payment await dbHelper.update(models.Issue, dbIssue.id, { diff --git a/utils/logger.js b/utils/logger.js index 473b392..d0f889a 100644 --- a/utils/logger.js +++ b/utils/logger.js @@ -32,7 +32,7 @@ logger.logFullError = function logFullError(err, signature) { if (!err || err.logged) { return; } - logger.error(`Error happened in ${signature}\n${err.stack}`); + logger.error(`Error happened in ${signature}\n${err.stack || err.message}`); err.logged = true; }; diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index 58b05ca..a57730b 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -76,7 +76,7 @@ async function createChallenge(challenge) { }], timelineTemplateId: config.DEFAULT_TIMELINE_TEMPLATE_ID, projectId: challenge.projectId, - tags: challenge.tags, + tags: challenge.tags.map((tag) => tag.name), trackId: config.DEFAULT_TRACK_ID, legacy: { pureV5Task: true @@ -163,6 +163,41 @@ async function activateChallenge(id) { } } +/** + * Apply skills set to the challenge + * @param {String} challengeId the challenge id + * @param {Array<{id: string, name: string}>} tags the list of tags applied to the challenge + */ +async function applySkillsSetToChallenge(challengeId, tags) { + const apiKey = await getM2Mtoken(); + logger.debug(`Applying skills set to the challenge ${challengeId}`); + const url = `${config.TC_API_URL}/standardized-skills/work-skills`; + const payload = { + workId: challengeId, + workTypeId: config.WORK_TYPE_ID, + skillIds: tags.map((tag) => tag.id) + }; + const params = { + headers: { + authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + } + }; + try { + const response = await axios.post(url, payload, params); + const statusCode = response.status ? response.status : null; + loggerFile.info(`EndPoint: POST /standardized-skills/work-skills, + POST parameters: ${circularJSON.stringify(payload)}, Status Code:${statusCode}, Response: ${circularJSON.stringify(response.data)}`); + logger.debug(`Skills set applied successfully to the challenge ${challengeId}`); + return response.data; + } catch (err) { + loggerFile.info(`EndPoint: POST /standardized-skills/work-skills, POST parameters: ${circularJSON.stringify(payload)}, Status Code:null, + Error: 'Failed to apply skills set to the challenge.', Details: ${circularJSON.stringify(err)}`); + logger.error(`Response Data: ${JSON.stringify(err.response.data)}`); + throw errors.convertTopcoderApiError(err, 'Failed to apply skills set to the challenge.'); + } +} + /** * Get challenge details by id * @param {String} id challenge ID @@ -511,6 +546,7 @@ module.exports = { createChallenge, updateChallenge, activateChallenge, + applySkillsSetToChallenge, closeChallenge, getProjectBillingAccountId, getTopcoderMemberId, From e309ee350d07734ee44c87784f7b28877f89c38b Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Tue, 21 Nov 2023 08:23:51 +1100 Subject: [PATCH 23/28] Change to use the new challenge-skills endpoint --- utils/topcoder-api-helper.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index a57730b..15504e7 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -171,10 +171,8 @@ async function activateChallenge(id) { async function applySkillsSetToChallenge(challengeId, tags) { const apiKey = await getM2Mtoken(); logger.debug(`Applying skills set to the challenge ${challengeId}`); - const url = `${config.TC_API_URL}/standardized-skills/work-skills`; + const url = `${config.TC_API_URL}/standardized-skills/challenge-skills/${challengeId}`; const payload = { - workId: challengeId, - workTypeId: config.WORK_TYPE_ID, skillIds: tags.map((tag) => tag.id) }; const params = { @@ -186,12 +184,12 @@ async function applySkillsSetToChallenge(challengeId, tags) { try { const response = await axios.post(url, payload, params); const statusCode = response.status ? response.status : null; - loggerFile.info(`EndPoint: POST /standardized-skills/work-skills, + loggerFile.info(`EndPoint: POST /standardized-skills/challenge-skills/${challengeId}, POST parameters: ${circularJSON.stringify(payload)}, Status Code:${statusCode}, Response: ${circularJSON.stringify(response.data)}`); logger.debug(`Skills set applied successfully to the challenge ${challengeId}`); return response.data; } catch (err) { - loggerFile.info(`EndPoint: POST /standardized-skills/work-skills, POST parameters: ${circularJSON.stringify(payload)}, Status Code:null, + loggerFile.info(`EndPoint: POST /standardized-skills/challenge-skills/${challengeId}, POST parameters: ${circularJSON.stringify(payload)}, Status Code:null, Error: 'Failed to apply skills set to the challenge.', Details: ${circularJSON.stringify(err)}`); logger.error(`Response Data: ${JSON.stringify(err.response.data)}`); throw errors.convertTopcoderApiError(err, 'Failed to apply skills set to the challenge.'); From 6c2547609b64d3ed4e2b00683fae67619be97341 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Fri, 24 Nov 2023 14:30:27 +0530 Subject: [PATCH 24/28] fix: TC challenge creation fails --- utils/topcoder-api-helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index a57730b..baa8590 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -76,7 +76,7 @@ async function createChallenge(challenge) { }], timelineTemplateId: config.DEFAULT_TIMELINE_TEMPLATE_ID, projectId: challenge.projectId, - tags: challenge.tags.map((tag) => tag.name), + tags: challenge.tags, trackId: config.DEFAULT_TRACK_ID, legacy: { pureV5Task: true From e056f933d4f0d792a2619b93d746b8fcced939d5 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha Date: Fri, 8 Dec 2023 09:00:34 +0530 Subject: [PATCH 25/28] fix: don't apply tags when creating/updating challenges --- services/ChallengeService.js | 6 ++++-- services/CopilotPaymentService.js | 1 - services/IssueService.js | 1 - utils/topcoder-api-helper.js | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/services/ChallengeService.js b/services/ChallengeService.js index 93fca2e..649f0c8 100644 --- a/services/ChallengeService.js +++ b/services/ChallengeService.js @@ -20,13 +20,15 @@ const dbHelper = require('../utils/db-helper'); * @param {Object} event the event */ async function handleChallengeTagsUpdate(event) { - const tags = event.data.tags.map((tag) => tag.name); + const tags = event.data.tags; await Promise.all( event.data.challengeUUIDsList.map(async (challengeUUIDs) => { if (_.isString(challengeUUIDs)) { // repoUrl challengeUUIDs = await dbHelper.queryChallengeUUIDsByRepoUrl(challengeUUIDs); } - return challengeUUIDs.map(async (challengeUUID) => await topcoderApiHelper.updateChallenge(challengeUUID, {tags})); + return challengeUUIDs.map( + async (challengeUUID) => await topcoderApiHelper.applySkillsSetToChallenge(challengeUUID, tags) + ); }).reduce((a, b) => _.concat(a, b), []) ).then((resps) => { logger.debug(`handleChallengeTagsUpdate updated ${_.size(resps)} challenges successfully.`); diff --git a/services/CopilotPaymentService.js b/services/CopilotPaymentService.js index 944d50e..df152a6 100644 --- a/services/CopilotPaymentService.js +++ b/services/CopilotPaymentService.js @@ -194,7 +194,6 @@ async function handlePaymentAdd(event, payment) { const newChallenge = { name: challengeTitle, projectId: project.tcDirectId, - tags: project.tags ? project.tags.map((tag) => tag.name) : [], detailedRequirements: challengeRequirements, prizes: [payment.amount], reviewType: 'INTERNAL' diff --git a/services/IssueService.js b/services/IssueService.js index 4986cc6..f7070a6 100755 --- a/services/IssueService.js +++ b/services/IssueService.js @@ -635,7 +635,6 @@ async function handleIssueCreate(event, issue, forceAssign = false) { issue.challengeUUID = await topcoderApiHelper.createChallenge({ name: issue.title, projectId, - tags: project.tags ? project.tags.map((tag) => tag.name) : [], detailedRequirements: issue.body, prizes: issue.prizes }); diff --git a/utils/topcoder-api-helper.js b/utils/topcoder-api-helper.js index 5d1484e..408d562 100644 --- a/utils/topcoder-api-helper.js +++ b/utils/topcoder-api-helper.js @@ -76,7 +76,7 @@ async function createChallenge(challenge) { }], timelineTemplateId: config.DEFAULT_TIMELINE_TEMPLATE_ID, projectId: challenge.projectId, - tags: challenge.tags, + tags: [], trackId: config.DEFAULT_TRACK_ID, legacy: { pureV5Task: true @@ -189,6 +189,7 @@ async function applySkillsSetToChallenge(challengeId, tags) { logger.debug(`Skills set applied successfully to the challenge ${challengeId}`); return response.data; } catch (err) { + // eslint-disable-next-line max-len loggerFile.info(`EndPoint: POST /standardized-skills/challenge-skills/${challengeId}, POST parameters: ${circularJSON.stringify(payload)}, Status Code:null, Error: 'Failed to apply skills set to the challenge.', Details: ${circularJSON.stringify(err)}`); logger.error(`Response Data: ${JSON.stringify(err.response.data)}`); From cd76764c6b39901da69d78dc95c04d0eb9ab1af1 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Tue, 2 Jan 2024 08:43:47 +1100 Subject: [PATCH 26/28] Additional logging and build fix for Docker 7 issues --- .circleci/config.yml | 1 + utils/errors.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index a49ecbc..1f62918 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,7 @@ install_dependency: &install_dependency sudo apt install jq sudo apt install python3-pip sudo pip3 install awscli --upgrade + sudo pip3 install docker==6.1.3 sudo pip3 install docker-compose install_deploysuite: &install_deploysuite name: Installation of install_deploysuite. diff --git a/utils/errors.js b/utils/errors.js index fe04aa0..52b7e52 100644 --- a/utils/errors.js +++ b/utils/errors.js @@ -13,6 +13,7 @@ const _ = require('lodash'); const constants = require('../constants'); const notification = require('./notification'); +const logger = require ('./logger'); // the error class wrapper class ProcessorError extends Error { @@ -49,6 +50,7 @@ errors.handleGitHubError = function handleGitHubError(err, message, copilotHandl resMsg, 'github' ); + logger.error(`Github error thrown: ${JSON.stringify(apiError)}`); return apiError; }; @@ -74,6 +76,7 @@ errors.handleGitLabError = function handleGitLabError(err, message, copilotHandl resMsg, 'gitlab' ); + logger.error(`Gitlab error thrown: ${JSON.stringify(apiError)}`); return apiError; }; @@ -94,6 +97,7 @@ errors.convertTopcoderApiError = function convertTopcoderApiError(err, message) resMsg, 'topcoder' ); + logger.error(`Topcoder error thrown: ${JSON.stringify(apiError)}`); return apiError; }; @@ -109,6 +113,7 @@ errors.internalDependencyError = function internalDependencyError(message) { resMsg, 'processor' ); + logger.error(`Internal API error thrown: ${JSON.stringify(apiError)}`); return apiError; }; From a9bea907c83c11c8db173c998f71738ebbd4ffe7 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Tue, 2 Jan 2024 09:00:23 +1100 Subject: [PATCH 27/28] Additional logging when refreshing the token --- services/GitlabService.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/GitlabService.js b/services/GitlabService.js index dccb512..b9f7e9a 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -146,6 +146,7 @@ class GitlabService { .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) .query(query) .end(); + logger.info(`Gitlab refresh token result: ${JSON.stringify(refreshTokenResult)}`); // save user token data const expiresIn = refreshTokenResult.body.expires_in || config.GITLAB_ACCESS_TOKEN_DEFAULT_EXPIRATION; const updates = { From 13e2911a3b645814a3cdacac9e73ea4f441718c2 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Tue, 2 Jan 2024 09:39:01 +1100 Subject: [PATCH 28/28] Additional logging --- services/GitlabService.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/GitlabService.js b/services/GitlabService.js index b9f7e9a..77ff183 100644 --- a/services/GitlabService.js +++ b/services/GitlabService.js @@ -142,6 +142,7 @@ class GitlabService { refresh_token: lockedUser.refreshToken, grant_type: 'refresh_token' }; + logger.info(`Refresh request POST ${config.GITLAB_API_BASE_URL}/oauth/token BODY: ${JSON.stringify(query)} `); const refreshTokenResult = await request .post(`${config.GITLAB_API_BASE_URL}/oauth/token`) .query(query)