diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..cb2690d0 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,40 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "name": "Nodemon TaaS API", + "program": "${workspaceFolder}/app.js", + "envFile": "${workspaceFolder}/.env", + "request": "launch", + "restart": true, + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/nodemon", + "skipFiles": [ + "/**" + ], + "type": "pwa-node" + }, + { + "type": "pwa-node", + "request": "launch", + "name": "Launch TaaS API", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/app.js", + "envFile": "${workspaceFolder}/.env", + "console": "integratedTerminal" + }, + { + "name": "Attach to dev:debug", + "type": "node", + "request": "attach", + "restart": true, + "port": 9229 + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9ce1b043 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +#!/bin/bash +GR=\033[92m>>> +NC= <<<\033[0m +.PHONY: dump_tables +dump_tables: + @echo "${GR}make sure you checked in all your changes${NC}" + @echo "${GR}going to dev${NC}" + git checkout dev + npm run services:down + npm run services:up + npm run init-db + npm run migrate + @echo "${GR}cool, we are now migrated to dev status... moving on to our branch${NC}" + git checkout feature/interview-nylas + npm run migrate + @echo "${GR}now we are post-feature migration state, let's dump the tables${NC}" + @mkdir -p ./.comparisons/migrate + @mkdir -p ./.comparisons/init-db + @docker exec -t tc-taas-postgres pg_dump -h localhost --username=postgres -t 'bookings.interviews' --schema-only postgres > ./.comparisons/migrate/interviews.sql + @docker exec -t tc-taas-postgres pg_dump -h localhost --username=postgres -t 'bookings.job_candidates' --schema-only postgres > ./.comparisons/migrate/job_candidates.sql + @docker exec -t tc-taas-postgres pg_dump -h localhost --username=postgres -t 'bookings.user_meeting_settings' --schema-only postgres > ./.comparisons/migrate/user_meeting_settings.sql + @echo "${GR}now we revert and simply `init-db force` from the feature branch${NC}" + npm run services:down + npm run services:up + npm run init-db force + @docker exec -t tc-taas-postgres pg_dump -h localhost --username=postgres -t 'bookings.interviews' --schema-only postgres > ./.comparisons/init-db/interviews.sql + @docker exec -t tc-taas-postgres pg_dump -h localhost --username=postgres -t 'bookings.job_candidates' --schema-only postgres > ./.comparisons/init-db/job_candidates.sql + @docker exec -t tc-taas-postgres pg_dump -h localhost --username=postgres -t 'bookings.user_meeting_settings' --schema-only postgres > ./.comparisons/init-db/user_meeting_settings.sql + @echo "${GR}All done, you can now compare the files${NC}" + git diff --no-index ./.comparisons/migrate/interviews.sql ./.comparisons/init-db/interviews.sql > ./.comparisons/interviews.diff || true + git diff --no-index ./.comparisons/migrate/job_candidates.sql ./.comparisons/init-db/job_candidates.sql > ./.comparisons/job_candidates.diff || true + git diff --no-index ./.comparisons/migrate/user_meeting_settings.sql ./.comparisons/init-db/user_meeting_settings.sql > ./.comparisons/user_meeting_settings.diff || true + + + +.PHONY: reboot +reboot: + npm run services:down + npm run services:up + npm run init-db + npm run migrate + npm run local:init || true + npm run test diff --git a/README.md b/README.md index a8215223..8746cd7f 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,15 @@ AUTH0_AUDIENCE_UBAHN= AUTH0_CLIENT_ID= AUTH0_CLIENT_SECRET= - # necessary if you'll utilize email functionality of interviews - INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID= - INTERVIEW_INVITATION_SENDER_EMAIL= + # If you would like to test Interview Workflow then Config Nylas as per ./docs/guides/Setup-Interview-Workflow-Locally.md + NYLAS_CLIENT_ID= + NYLAS_CLIENT_SECRET= + NYLAS_SCHEDULER_WEBHOOK_BASE_URL= # Locally deployed services (via docker-compose) ES_HOST=http://dockerhost:9200 DATABASE_URL=postgres://postgres:postgres@dockerhost:5432/postgres BUSAPI_URL=http://dockerhost:8002/v5 + TAAS_API_BASE_URL=http://localhost:3000/api/v5 # stripe STRIPE_SECRET_KEY= CURRENCY=usd @@ -55,7 +57,7 @@ - Values from this file would be automatically used by many `npm` commands. - ⚠️ Never commit this file or its copy to the repository! - 1. Set `dockerhost` to point the IP address of Docker. Docker IP address depends on your system. For example if docker is run on IP `127.0.0.1` add a the next line to your `/etc/hosts` file: + 2. Set `dockerhost` to point the IP address of Docker. Docker IP address depends on your system. For example if docker is run on IP `127.0.0.1` add a the next line to your `/etc/hosts` file: ``` 127.0.0.1 dockerhost @@ -170,6 +172,8 @@ Runs the Topcoder TaaS API using nodemon, so it would be restarted after any of the files is updated. The Topcoder TaaS API will be served on `http://localhost:3000`. + - 💡 If you would like to test Interview Workflow locally, then follow the guide [How to Setup Interview Workflow Locally](./docs/guides/Setup-Interview-Workflow-Locally.md). + ### Working on `taas-es-processor` locally When you run `taas-apis` locally as per "[Steps to run locally](#steps-to-run-locally)" the [taas-es-processor](https://github.com/topcoder-platform/taas-es-processor) would be run for you automatically together with other services inside the docker container via `npm run services:up`. @@ -224,7 +228,7 @@ To be able to change and test `taas-es-processor` locally you can follow the nex | `npm run cov` | Code Coverage Report. | | `npm run migrate` | Run any migration files which haven't run yet. | | `npm run migrate:undo` | Revert most recent migration. | -| `npm run demo-payment-scheduler` | Create 1000 Work Periods Payment records in with status "scheduled" and various "amount" | +| `npm run demo-email-notifications` | Listen to the Kafka events of email notification and render all the emails into `./out` folder. See [its readme](scripts/demo-email-notifications/README.md) for details. | | `npm run emsi-mapping` | mapping EMSI tags to topcoder skills | ## Import and Export data @@ -294,6 +298,29 @@ docker exec -it tc-taas-kafka /opt/kafka/bin/kafka-console-producer.sh --broker- - Enter or copy/paste the message into the console after starting this command. +## Email Notifications + +We have various email notifications. For example many emails are sent to support Interview Scheduling Workflow. All email templates are placed inside the [.data/notification-email-templates](./data/notification-email-templates/) folder. + +### Add a new Email Notification + +To add a new email notification: + +0. Each email notification need to have a unique topic identifier of the shape `taas.notification.{notification-type}`. Where `{notification-type}` is unique for each email notification type. +1. Create a new HTML template inside folder [.data/notification-email-templates](./data/notification-email-templates/). (You may duplicate any existent template to reuse existent styles.). Name it the same as topic: `taas.notification.{notification-type}.html`. +2. Create a corresponding config in file [./config/email_template.config.js](./config/email_template.config.js), section `notificationEmailTemplates`. +3. Name environment variable the same as topic, but **uppercase** and replace all special symbols to `_` and add suffix `_SENDGRID_TEMPLATE_ID`: + - For example topic `taas.notification.job-candidate-resume-viewed` would have corresponding environment variable +`TAAS_NOTIFICATION_JOB_CANDIDATE_RESUME_VIEWED_SENDGRID_TEMPLATE_ID`. +4. When deploying to DEV/PROD someone would have to create a new Sendgird template and fill inside Sendgrid UI subject and email HTML template by copy/pasting HTML file from the repo. And then set environment variable with the value of template if provided by Sendgrid. + +### Test/Render Email Notifications Locally + +To test and render email notification locally run a special script `npm run demo-email-notifications`. Before running it, follow it's [README](./scripts/demo-email-notifications/README.md) as you would have to set some additional environment variables first (add them into `.env` file). + +- This script first would update demo data to create some situations to trigger notifications. +- And it would listen to Kafka events and render email notification into `./out` folder. + ## DB Migration - `npm run migrate`: run any migration files which haven't run yet. @@ -303,10 +330,7 @@ Configuration for migration is at `./config/config.json`. The following parameters can be set in the config file or via env variables: -- `username`: set via env `DB_USERNAME`; datebase username -- `password`: set via env `DB_PASSWORD`; datebase password -- `database`: set via env `DB_NAME`; datebase name -- `host`: set via env `DB_HOST`; datebase host name +- `url`: set via env `DATABASE_URL`; datebase url ## Testing @@ -341,6 +365,7 @@ When we add, update or delete models and/or endpoints we have to make sure that - Test, that when we migrate DB from the previous state using `npm run migrate`, we get exactly the same DB schema as if we create DB from scratch using command `npm run init-db force`. ## EMSI mapping + mapping EMSI tags to topcoder skills Run `npm run emsi-mapping` to create the mapping file It will take about 15 minutes to create the mapping file `script/emsi-mapping/emsi-skils-mapping.js` diff --git a/app-constants.js b/app-constants.js index 6f53dfd4..cc1db71f 100644 --- a/app-constants.js +++ b/app-constants.js @@ -58,7 +58,13 @@ const Scopes = { CREATE_ROLE: 'create:taas-roles', UPDATE_ROLE: 'update:taas-roles', DELETE_ROLE: 'delete:taas-roles', - ALL_ROLE: 'all:taas-roles' + ALL_ROLE: 'all:taas-roles', + // userMeetingSettings + READ_USER_MEETING_SETTINGS: 'read:taas-userMeetingsSettings', + CREATE_USER_MEETING_SETTINGS: 'create:taas-userMeetingsSettings', + UPDATE_USER_MEETING_SETTINGS: 'update:taas-userMeetingsSettings', + ALL_USER_MEETING_SETTINGS: 'all:taas-userMeetingsSettings' + } // Interview related constants @@ -69,14 +75,22 @@ const Interviews = { RequestedForReschedule: 'Requested for reschedule', Rescheduled: 'Rescheduled', Completed: 'Completed', - Cancelled: 'Cancelled' - }, - // key: template name in x.ai, value: duration - XaiTemplate: { - 'interview-30': 30, - 'interview-60': 60 + Cancelled: 'Cancelled', + Expired: 'Expired' }, - MaxAllowedCount: 3 + MaxAllowedCount: 3, + Nylas: { + Days: { + Monday: 'M', + Tuesday: 'T', + Wednesday: 'W', + Thursday: 'R', + Friday: 'F', + Saturday: 'S', + Sunday: 'U' + }, + StartEndRegex: /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/ + } } const ChallengeStatus = { @@ -166,7 +180,23 @@ const JobCandidateStatus = { INTERVIEW: 'interview' } +const SearchUsers = { + SEARCH_USERS_PAGE_SIZE: 5 +} + +// provider which we have to enforce for Nylas Virtual Calendars +const NylasVirtualCalendarProvider = 'nylas' + +const ZoomLinkType = { + HOST: 'host', + GUEST: 'guest' +} + +// how long to wait for the Interview Webhook Mutes to release (ms) +const InterviewEventHandlerTimeout = 60 * 1000 // 60 seconds + module.exports = { + InterviewEventHandlerTimeout, UserRoles, FullManagePermissionRoles, Scopes, @@ -181,5 +211,8 @@ module.exports = { WeeklySurveySwitch, ActiveWorkPeriodPaymentStatuses, JobStatus, - JobCandidateStatus + JobCandidateStatus, + SearchUsers, + NylasVirtualCalendarProvider, + ZoomLinkType } diff --git a/app.js b/app.js index 6e45efc0..3195bd54 100644 --- a/app.js +++ b/app.js @@ -25,7 +25,32 @@ app.use(cors({ // Allow browsers access pagination data in headers exposedHeaders: ['X-Page', 'X-Per-Page', 'X-Total', 'X-Total-Pages', 'X-Prev-Page', 'X-Next-Page'] })) -app.use(express.json()) +app.use((...args) => { + const [req, res, next] = args + // For test nylas webhook, we need raw buffer + // Here i sCustom Middleware to compute rawBody. Unfortunately using + // JSON.stringify(req.body) will remove spaces and newlines, so verification + // will fail. We must add this middleware to ensure we're computing the correct + // signature + if (req.path.match(/\/taas-teams\/nylas-webhooks/i)) { + req.rawBody = '' + req.on('data', (chunk) => (req.rawBody += chunk)) + req.on('error', () => res.status(500).send('Error parsing body')) + + req.on('end', () => { + // because the stream has been consumed, other parsers like bodyParser.json + // cannot stream the request data and will time out so we must explicitly parse the body + try { + req.body = req.rawBody.length ? JSON.parse(req.rawBody) : {} + next() + } catch (err) { + res.status(500).send('Error parsing body') + } + }) + return + } + return express.json()(...args) +}) app.use(express.urlencoded({ extended: true })) app.set('port', config.PORT) @@ -100,7 +125,7 @@ const server = app.listen(app.get('port'), () => { logger.info({ component: 'app', message: `Express server listening on port ${app.get('port')}` }) eventHandlers.init() // schedule updateCompletedInterviews to run every hour - schedule.scheduleJob('0 0 * * * *', interviewService.updateCompletedInterviews) + schedule.scheduleJob(config.CRON_UPDATE_COMPLETED_INTERVIEWS, interviewService.updateCompletedInterviews) // schedule sendSurveys if (WeeklySurveySwitch.ON === config.WEEKLY_SURVEY.SWITCH) { schedule.scheduleJob(config.WEEKLY_SURVEY.CRON, sendSurveys) @@ -113,6 +138,9 @@ const server = app.listen(app.get('port'), () => { schedule.scheduleJob(config.CRON_INTERVIEW_COMPLETED, notificationSchedulerService.sendInterviewCompletedNotifications) schedule.scheduleJob(config.CRON_POST_INTERVIEW, notificationSchedulerService.sendPostInterviewActionNotifications) schedule.scheduleJob(config.CRON_UPCOMING_RESOURCE_BOOKING, notificationSchedulerService.sendResourceBookingExpirationNotifications) + + schedule.scheduleJob(config.CRON_INTERVIEW_EXPIRED, notificationSchedulerService.sendInterviewExpiredNotifications) + schedule.scheduleJob(config.CRON_INTERVIEW_SCHEDULE_REMINDER, notificationSchedulerService.sendInterviewScheduleReminderNotifications) }) if (process.env.NODE_ENV === 'test') { diff --git a/config/config.js b/config/config.js index 34edf647..3b6d0e29 100644 --- a/config/config.js +++ b/config/config.js @@ -4,24 +4,12 @@ module.exports = { development: { - username: process.env.DB_USERNAME || 'postgres', - password: process.env.DB_PASSWORD || 'postgres', - database: process.env.DB_NAME || 'postgres', - host: process.env.DB_HOST || '127.0.0.1', - dialect: 'postgres' + url: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/postgres' }, test: { - username: process.env.DB_USERNAME || 'postgres', - password: process.env.DB_PASSWORD || 'postgres', - database: process.env.DB_NAME || 'postgres', - host: process.env.DB_HOST || '127.0.0.1', - dialect: 'postgres' + url: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/postgres' }, production: { - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, - host: process.env.DB_HOST, - dialect: 'postgres' + url: process.env.DATABASE_URL } } diff --git a/config/default.js b/config/default.js index 319720ab..34470f55 100644 --- a/config/default.js +++ b/config/default.js @@ -82,6 +82,8 @@ module.exports = { ES_INDEX_RESOURCE_BOOKING: process.env.ES_INDEX_RESOURCE_BOOKING || 'resource_booking', // the role index ES_INDEX_ROLE: process.env.ES_INDEX_ROLE || 'role', + // the userMeetingSettings index + ES_INDEX_USER_MEETING_SETTINGS: process.env.ES_INDEX_USER_MEETING_SETTINGS || 'user_meeting_settings', // the max bulk size in MB for ES indexing MAX_BULK_REQUEST_SIZE_MB: process.env.MAX_BULK_REQUEST_SIZE_MB || 20, @@ -166,7 +168,6 @@ module.exports = { // INTERVIEW_INVITATION_CC_LIST may contain comma-separated list of email which is converted to array INTERVIEW_INVITATION_CC_LIST: (process.env.INTERVIEW_INVITATION_CC_LIST || '').split(','), // INTERVIEW_INVITATION_RECIPIENTS_LIST may contain comma-separated list of email which is converted to array - // scheduler@x.ai should be in the RECIPIENTS list INTERVIEW_INVITATION_RECIPIENTS_LIST: (process.env.INTERVIEW_INVITATION_RECIPIENTS_LIST || 'scheduler@topcoder.com').split(','), // the emails address for overlapping interview NOTIFICATION_OPS_EMAILS: (process.env.NOTIFICATION_OPS_EMAILS || 'overlapping@topcoder.com').split(','), @@ -176,12 +177,17 @@ module.exports = { REPORT_ISSUE_SENDGRID_TEMPLATE_ID: process.env.REPORT_ISSUE_SENDGRID_TEMPLATE_ID, // SendGrid email template ID for requesting extension REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID: process.env.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID, - // SendGrid email template ID for interview invitation - INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID: process.env.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID, - // The sender (aka `from`) email for invitation. - INTERVIEW_INVITATION_SENDER_EMAIL: process.env.INTERVIEW_INVITATION_SENDER_EMAIL || 'talent@topcoder.com', + + // Duration that gets added to current time when an interview is created in order to calculate expireTimestamp + INTERVIEW_SCHEDULING_EXPIRE_TIME: process.env.INTERVIEW_SCHEDULING_EXPIRE_TIME || 'P5D', // the URL where TaaS App is hosted TAAS_APP_URL: process.env.TAAS_APP_URL || 'https://platform.topcoder-dev.com/taas/myteams', + TAAS_APP_BASE_URL: process.env.TAAS_APP_BASE_URL || 'https://platform.topcoder-dev.com/taas', + TAAS_APP_BFF_BASE_URL: process.env.TAAS_APP_BFF_BASE_URL || 'https://platform.topcoder-dev.com/taas-app', + // the URL where TaaS App Earn is hosted + TAAS_APP_EARN_URL: process.env.TAAS_APP_EARN_URL || 'https://platform.topcoder-dev.com/earn/my-gigs', + // the URL where TaaS API is hosted + TAAS_API_BASE_URL: process.env.TAAS_API_BASE_URL || 'https://api.topcoder-dev.com/v5', // environment variables for Payment Service 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', @@ -254,8 +260,52 @@ module.exports = { }, // the sender email NOTIFICATION_SENDER_EMAIL: process.env.NOTIFICATION_SENDER_EMAIL || 'noreply@topcoder.com', - // the email notification sendgrid template id - NOTIFICATION_SENDGRID_TEMPLATE_ID: process.env.NOTIFICATION_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of candidate was viewed by client + TAAS_NOTIFICATION_JOB_CANDIDATE_RESUME_VIEWED_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_JOB_CANDIDATE_RESUME_VIEWED_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of candidates are available for review + TAAS_NOTIFICATION_CANDIDATES_AVAILABLE_FOR_REVIEW_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_CANDIDATES_AVAILABLE_FOR_REVIEW_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview coming up for customer + TAAS_NOTIFICATION_INTERVIEW_COMING_UP_HOST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_COMING_UP_HOST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview coming up for member + TAAS_NOTIFICATION_INTERVIEW_COMING_UP_GUEST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_COMING_UP_GUEST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview completed + TAAS_NOTIFICATION_INTERVIEW_AWAITS_RESOLUTION_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_AWAITS_RESOLUTION_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of post interview action reminder + TAAS_NOTIFICATION_POST_INTERVIEW_ACTION_REQUIRED_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_POST_INTERVIEW_ACTION_REQUIRED_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of upcoming resource booking expiration + TAAS_NOTIFICATION_RESOURCE_BOOKING_EXPIRATION_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_RESOURCE_BOOKING_EXPIRATION_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of new team created + TAAS_NOTIFICATION_TEAM_CREATED_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_TEAM_CREATED_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of new job added to existing project + TAAS_NOTIFICATION_JOB_CREATED_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_JOB_CREATED_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of resource placed + TAAS_NOTIFICATION_RESOURCE_BOOKING_PLACED_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_RESOURCE_BOOKING_PLACED_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interviews overlapping + TAAS_NOTIFICATION_INTERVIEWS_OVERLAPPING_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEWS_OVERLAPPING_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of job candidate selected + TAAS_NOTIFICATION_JOB_CANDIDATE_SELECTED_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_JOB_CANDIDATE_SELECTED_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview schedule reminder for job candidate + TAAS_NOTIFICATION_INTERVIEW_SCHEDULE_REMINDER_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_SCHEDULE_REMINDER_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview expired for customer + TAAS_NOTIFICATION_INTERVIEW_EXPIRED_GUEST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_EXPIRED_GUEST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview expired for member + TAAS_NOTIFICATION_INTERVIEW_EXPIRED_HOST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_EXPIRED_HOST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of host + TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_HOST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_HOST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of guest + TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_GUEST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_GUEST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview rescheduled for host + TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_HOST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_HOST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview rescheduled for guest + TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_GUEST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_GUEST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview cancelled for host + TAAS_NOTIFICATION_INTERVIEW_CANCELLED_HOST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_CANCELLED_HOST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of interview cancelled for guest + TAAS_NOTIFICATION_INTERVIEW_CANCELLED_GUEST_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_CANCELLED_GUEST_SENDGRID_TEMPLATE_ID, + // the email notification sendgrid template id of job candidate invited + TAAS_NOTIFICATION_INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID: process.env.TAAS_NOTIFICATION_INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID, + // frequency of cron update scheduled or rescheduled interview to completed status + CRON_UPDATE_COMPLETED_INTERVIEWS: process.env.CRON_UPDATE_COMPLETED_INTERVIEWS || '0 0 * * * *', // frequency of cron checking for available candidates for review CRON_CANDIDATE_REVIEW: process.env.CRON_CANDIDATE_REVIEW || '00 00 13 * * 0-6', // frequency of cron checking for coming up interviews @@ -264,6 +314,10 @@ module.exports = { // frequency of cron checking for interview completed // when changing this to frequency other than 5 mins, please change the minutesRange in sendInterviewCompletedEmails correspondingly CRON_INTERVIEW_COMPLETED: process.env.CRON_INTERVIEW_COMPLETED || '*/5 * * * *', + // frequency of checking expired interview + CRON_INTERVIEW_EXPIRED: process.env.CRON_INTERVIEW_EXPIRED || '*/5 * * * *', + // frequency of checking interview schedule status which need remind job candidate to select time + CRON_INTERVIEW_SCHEDULE_REMINDER: process.env.CRON_INTERVIEW_SCHEDULE_REMINDER || '*/5 * * * *', // frequency of cron checking for post interview actions CRON_POST_INTERVIEW: process.env.CRON_POST_INTERVIEW || '00 00 13 * * 0-6', // frequency of cron checking for upcoming resource bookings @@ -272,10 +326,18 @@ module.exports = { INTERVIEW_COMING_UP_MATCH_WINDOW: process.env.INTERVIEW_COMING_UP_MATCH_WINDOW || 'PT5M', // The remind time for fetching interviews which are coming up INTERVIEW_COMING_UP_REMIND_TIME: (process.env.INTERVIEW_COMING_UP_REMIND_TIME || 'PT1H,PT24H').split(','), + // The match window for fetching schedule reminder interviews + INTERVIEW_SCHEDULE_REMINDER_WINDOW: process.env.INTERVIEW_SCHEDULE_REMINDER_WINDOW || 'PT5M', // The match window for fetching completed interviews INTERVIEW_COMPLETED_MATCH_WINDOW: process.env.INTERVIEW_COMPLETED_MATCH_WINDOW || 'PT5M', // The interview completed past time for fetching interviews INTERVIEW_COMPLETED_PAST_TIME: process.env.INTERVIEW_COMPLETED_PAST_TIME || 'PT4H', + // Reminder after days if Job Candidate hasn't selected time + INTERVIEW_REMINDER_DAY_AFTER: process.env.INTERVIEW_REMINDER_DAY_AFTER || 'P1D', + // Reminder frequency if Job Candidate hasn't selected time, unit: day + INTERVIEW_REMINDER_FREQUENCY: parseInt(process.env.INTERVIEW_REMINDER_FREQUENCY) || 1, + // How far in the feature we may allow scheduling interview, unit: day + INTERVIEW_AVAILABLE_DAYS_IN_FEATURE: parseInt(process.env.INTERVIEW_AVAILABLE_DAYS_IN_FEATURE) || 15, // The time before resource booking expiry when we should start sending notifications RESOURCE_BOOKING_EXPIRY_TIME: process.env.RESOURCE_BOOKING_EXPIRY_TIME || 'P21D', // The match window for fetching post interview actions @@ -284,5 +346,21 @@ module.exports = { STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY, CURRENCY: process.env.CURRENCY || 'usd', // RCRM base URL - RCRM_APP_URL: process.env.RCRM_APP_URL || 'https://app.recruitcrm.io' + RCRM_APP_URL: process.env.RCRM_APP_URL || 'https://app.recruitcrm.io', + + // Nylas Client id + NYLAS_CLIENT_ID: process.env.NYLAS_CLIENT_ID, + NYLAS_CLIENT_SECRET: process.env.NYLAS_CLIENT_SECRET, + NYLAS_SCHEDULER_WEBHOOK_SECRET: process.env.NYLAS_SCHEDULER_WEBHOOK_SECRET || 'dummy-secret-for-local-testing-only', + NYLAS_SCHEDULER_WEBHOOK_BASE_URL: process.env.NYLAS_SCHEDULER_WEBHOOK_BASE_URL || 'https://api.topcoder-dev.com/v5', + // We don't have to keep it secret, we use this JWT token just to compress data, not to secure it + NYLAS_CONNECT_CALENDAR_JWT_SECRET: process.env.NYLAS_CONNECT_CALENDAR_JWT_SECRET || 'secret', + + // Zoom JWT credentials + ZOOM_ACCOUNTS: process.env.ZOOM_ACCOUNTS, + + // The secret key for get zoom link token + ZOOM_LINK_SECRET: process.env.ZOOM_LINK_SECRET || 'zoom-link-secret', + // The get zoom link token expiry time + ZOOM_LINK_TOKEN_EXPIRY: process.env.ZOOM_LINK_TOKEN_EXPIRY || '180d' } diff --git a/config/email_template.config.js b/config/email_template.config.js index 524d54f1..aa8c7644 100644 --- a/config/email_template.config.js +++ b/config/email_template.config.js @@ -63,48 +63,8 @@ module.exports = { '{{text}}', recipients: config.REPORT_ISSUE_EMAILS, sendgridTemplateId: config.REQUEST_EXTENSION_SENDGRID_TEMPLATE_ID - }, - - /* Request interview for a job candidate - * - * - interviewType: the x.ai interview type. Example: "interview-30" - * - interviewRound: the round of the interview. Example: 2 - * - interviewDuration: duration of the interview, in minutes. Example: 30 - * - interviewerList: The list of interviewer email addresses. Example: "first@attendee.com, second@attendee.com" - * - candidateId: the id of the jobCandidate. Example: "cc562545-7b75-48bf-87e7-50b3c57e41b1" - * - candidateName: Full name of candidate. Example: "John Doe" - * - jobName: The title of the job. Example: "TaaS API Misc Updates" - * - * Template (defined in SendGrid): - * Subject: '{{interviewType}} tech interview with {{candidateName}} for {{jobName}} is requested by the Customer' - * Body: - * 'Hello! - *

- * Congratulations, you have been selected to participate in a Topcoder Gig Work Interview! - *

- * Please monitor your email for a response to this where you can coordinate your availability. - *

- * Interviewee: {{candidateName}}
- * Interviewer(s): {{interviewerList}}
- * Interview Length: {{interviewDuration}} minutes - *

- * /{{interviewType}} - *

- * Topcoder Info:
- * Note: "id: {{candidateId}}, round: {{interviewRound}}"' - * - * Note, that the template should be defined in SendGrid. - * The subject & body above (identical to actual SendGrid template) is for reference purposes. - * We won't pass subject & body but only substitutions (replacements in template subject/body). - */ - 'interview-invitation': { - subject: '', - body: '', - from: config.INTERVIEW_INVITATION_SENDER_EMAIL, - cc: config.INTERVIEW_INVITATION_CC_LIST, - recipients: config.INTERVIEW_INVITATION_RECIPIENTS_LIST, - sendgridTemplateId: config.INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID } + }, /** @@ -112,88 +72,158 @@ module.exports = { */ notificationEmailTemplates: { 'taas.notification.job-candidate-resume-viewed': { - subject: 'Topcoder - Client View Resume for Job {{jobName}}', + subject: 'Client has viewed your Topcoder profile', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_JOB_CANDIDATE_RESUME_VIEWED_SENDGRID_TEMPLATE_ID }, 'taas.notification.candidates-available-for-review': { - subject: 'Topcoder - {{teamName}} has job candidates available for review', + subject: 'You have candidates to review', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_CANDIDATES_AVAILABLE_FOR_REVIEW_SENDGRID_TEMPLATE_ID }, 'taas.notification.interview-coming-up-host': { - subject: 'Topcoder - Interview Coming Up: {{jobTitle}} with {{guestFullName}}', + subject: 'Interview reminder: Your Topcoder interview is coming up', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_COMING_UP_HOST_SENDGRID_TEMPLATE_ID }, 'taas.notification.interview-coming-up-guest': { - subject: 'Topcoder - Interview Coming Up: {{jobTitle}} with {{hostFullName}}', + subject: 'Reminder: Interview coming up', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_COMING_UP_GUEST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-rescheduled-host': { + subject: 'Your interview has been rescheduled to {{start}}', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_HOST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-rescheduled-guest': { + subject: 'Your interview has been rescheduled to {{start}}', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_GUEST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-cancelled-host': { + subject: 'Your interview on {{start}} has been cancelled', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_CANCELLED_HOST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-cancelled-guest': { + subject: 'Your interview on {{start}} has been cancelled', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_CANCELLED_GUEST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-invitation': { + subject: 'Schedule your interview for {{jobTitle}}', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-link-for-host': { + subject: 'Your candidate interview is confirmed! {{start}}', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_HOST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-link-for-guest': { + subject: 'Your interview is confirmed! {{start}}', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_GUEST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-expired-host': { + subject: 'Interview expired - your candidate didn\'t select time', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_EXPIRED_HOST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-expired-guest': { + subject: 'Your interview invitation is expired', + body: '', + recipients: [], + from: config.NOTIFICATION_SENDER_EMAIL, + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_EXPIRED_GUEST_SENDGRID_TEMPLATE_ID + }, + 'taas.notification.interview-schedule-reminder': { + subject: 'ACTION REQUIRED: Schedule your interview', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_SCHEDULE_REMINDER_SENDGRID_TEMPLATE_ID }, 'taas.notification.interview-awaits-resolution': { - subject: 'Topcoder - Interview Awaits Resolution: {{jobTitle}} for {{guestFullName}}', + subject: 'Interview complete - here’s what to do next', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEW_AWAITS_RESOLUTION_SENDGRID_TEMPLATE_ID }, 'taas.notification.post-interview-action-required': { - subject: 'Topcoder - Candidate Action Required in {{teamName}} for {{numCandidates}} candidates', + subject: 'Reminder: Take action to reserve your talent', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_POST_INTERVIEW_ACTION_REQUIRED_SENDGRID_TEMPLATE_ID }, 'taas.notification.resource-booking-expiration': { - subject: 'Topcoder - Resource Booking Expiring in {{teamName}} for {{numResourceBookings}} resource bookings', + subject: 'Reminder: 3 weeks left for your Topcoder Freelancer(s)', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_RESOURCE_BOOKING_EXPIRATION_SENDGRID_TEMPLATE_ID }, 'taas.notification.team-created': { - subject: 'Topcoder - New Team {{teamName}} Created', + subject: 'Your Topcoder talent request confirmation', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_TEAM_CREATED_SENDGRID_TEMPLATE_ID }, 'taas.notification.job-created': { - subject: 'Topcoder - New Job {{jobTitle}} Created in Team {{teamName}}', + subject: 'New job added to your Topcoder team', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_JOB_CREATED_SENDGRID_TEMPLATE_ID }, 'taas.notification.interviews-overlapping': { subject: 'Topcoder - Interviews overlapping', body: '', recipients: config.NOTIFICATION_OPS_EMAILS, from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_INTERVIEWS_OVERLAPPING_SENDGRID_TEMPLATE_ID }, 'taas.notification.job-candidate-selected': { subject: 'Topcoder - Job Candidate {{userHandle}} Selected for {{jobTitle}} in Team {{teamName}}', body: '', recipients: config.NOTIFICATION_OPS_EMAILS, from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_JOB_CANDIDATE_SELECTED_SENDGRID_TEMPLATE_ID }, 'taas.notification.resource-booking-placed': { - subject: 'Topcoder - Resource Booking {{userHandle}} Placed for Job {{jobTitle}} in Team {{teamName}}', + subject: 'Your Topcoder talent is confirmed! How to start working with them.', body: '', recipients: [], from: config.NOTIFICATION_SENDER_EMAIL, - sendgridTemplateId: config.NOTIFICATION_SENDGRID_TEMPLATE_ID + sendgridTemplateId: config.TAAS_NOTIFICATION_RESOURCE_BOOKING_PLACED_SENDGRID_TEMPLATE_ID } } } diff --git a/data/demo-data.json b/data/demo-data.json index 3df6f98c..97608601 100644 --- a/data/demo-data.json +++ b/data/demo-data.json @@ -852,24 +852,25 @@ "interviews": [ { "id": "077aa2ca-5b60-4ad9-a965-1b37e08a5046", - "xaiId": null, "jobCandidateId": "881a19de-2b0c-4bb9-b36a-4cb5e223bdb5", - "calendarEventId": null, - "templateUrl": "interview-30", - "templateId": null, - "templateType": null, - "title": null, - "locationDetails": null, + "nylasPageId": "56f526b8-ef68-48ef-954e-94ce5331653c", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "b3b0ebdb-3379-4971-8abd-d2d840af5b09", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "c3d4fbf3-2269-4ebc-a0fe-c4af094997e6", + "nylasPageSlug": "tc-taas-interview-077aa2ca-5b60-4ad9-a965-1b37e08a5046", "duration": null, "round": 1, "startTimestamp": null, "endTimestamp": null, - "hostName": null, - "hostEmail": "interviewhost@tc.com", - "guestNames": ["guest name1", "guest name2"], - "guestEmails": ["guest1@tc.com", "guest2@tc.com"], "status": "Completed", - "rescheduleUrl": null, "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-05-09T21:16:10.887Z", @@ -893,24 +894,25 @@ "interviews": [ { "id": "b1f7ba76-640f-47e2-9463-59e51b51ec60", - "xaiId": null, "jobCandidateId": "827ee401-df04-42e1-abbe-7b97ce7937ff", - "calendarEventId": null, - "templateUrl": "interview-30", - "templateId": null, - "templateType": null, - "title": null, - "locationDetails": null, + "nylasPageId": "c7ae492a-754d-4aec-89bd-e9b6f720d2c7", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "f5b672a9-228c-4041-9761-ab7bc9a5dd64", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "319ac38a-fdfe-48c1-9669-0b03f18c9354", + "nylasPageSlug": "tc-taas-interview-b1f7ba76-640f-47e2-9463-59e51b51ec60", "duration": null, "round": 2, "startTimestamp": null, "endTimestamp": null, - "hostName": null, - "hostEmail": "interviewhost@tc.com", - "guestNames": ["guest name1", "guest name2"], - "guestEmails": ["guest1@tc.com", "guest2@tc.com"], "status": "Scheduling", - "rescheduleUrl": null, "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-05-09T21:17:23.517Z", @@ -919,24 +921,25 @@ }, { "id": "3144fa65-ea1a-4bec-81b0-7cb1c8845826", - "xaiId": null, "jobCandidateId": "827ee401-df04-42e1-abbe-7b97ce7937ff", - "calendarEventId": null, - "templateUrl": "interview-30", - "templateId": null, - "templateType": null, - "title": null, - "locationDetails": null, + "nylasPageId": "d616f2f6-4d4a-45ae-aecf-22861ab3f409", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "785735", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "902bb544-594a-4667-9646-460171c4efa0", + "nylasPageSlug": "tc-taas-interview-3144fa65-ea1a-4bec-81b0-7cb1c8845826", "duration": null, "round": 1, "startTimestamp": null, "endTimestamp": null, - "hostName": null, - "hostEmail": "interviewhost@tc.com", - "guestNames": ["guest name1", "guest name2"], - "guestEmails": ["guest1@tc.com", "guest2@tc.com"], "status": "Completed", - "rescheduleUrl": null, "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-05-09T21:16:39.019Z", @@ -960,24 +963,25 @@ "interviews": [ { "id": "976d23a9-5710-453f-99d9-f57a588bb610", - "xaiId": null, "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", - "calendarEventId": null, - "templateUrl": "interview-30", - "templateId": null, - "templateType": null, - "title": null, - "locationDetails": null, + "nylasPageId": "2d64d37c-79f9-4a00-8916-79d08c936973", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "785735", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "dfc118c9-cdc6-4716-a8c5-763b5ff2383c", + "nylasPageSlug": "tc-taas-interview-976d23a9-5710-453f-99d9-f57a588bb610", "duration": null, "round": 3, "startTimestamp": null, "endTimestamp": null, - "hostName": null, - "hostEmail": "interviewhost@tc.com", - "guestNames": ["guest name1", "guest name2"], - "guestEmails": ["guest1@tc.com", "guest2@tc.com"], "status": "Scheduling", - "rescheduleUrl": null, "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-05-09T21:21:28.713Z", @@ -986,24 +990,52 @@ }, { "id": "a23e1bf2-1084-4cfe-a0d8-d83bc6fec655", - "xaiId": null, "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", - "calendarEventId": null, - "templateUrl": "interview-30", - "templateId": null, - "templateType": null, - "title": null, - "locationDetails": null, + "nylasPageId": "0f432417-9883-409d-a99a-df22942280f0", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "785735", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "f3e3a400-44e9-445a-96b4-adff39b0344d", + "nylasPageSlug": "tc-taas-interview-a23e1bf2-1084-4cfe-a0d8-d83bc6fec655", + "duration": null, + "round": 2, + "startTimestamp": null, + "endTimestamp": null, + "status": "Scheduling", + "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", + "updatedBy": null, + "createdAt": "2021-05-09T21:21:22.428Z", + "updatedAt": "2021-05-09T21:21:22.428Z", + "deletedAt": null + }, + { + "id": "505db942-79fe-4b6f-974c-b359e1b61967", + "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", + "nylasPageId": "4aae1d32-1d35-4320-be74-82a73bf032fa", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "785735", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "f3e3a400-44e9-445a-96b4-adff39b0344d", + "nylasPageSlug": "tc-taas-interview-505db942-79fe-4b6f-974c-b359e1b61967", "duration": null, "round": 2, "startTimestamp": null, "endTimestamp": null, - "hostName": null, - "hostEmail": "interviewhost@tc.com", - "guestNames": ["guest name1", "guest name2"], - "guestEmails": ["guest1@tc.com", "guest2@tc.com"], "status": "Scheduling", - "rescheduleUrl": null, "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-05-09T21:21:22.428Z", @@ -1012,24 +1044,25 @@ }, { "id": "9efd72c3-1dc7-4ce2-9869-8cca81d0adeb", - "xaiId": null, "jobCandidateId": "a4ea7bcf-5b99-4381-b99c-a9bd05d83a36", - "calendarEventId": null, - "templateUrl": "interview-30", - "templateId": null, - "templateType": null, - "title": null, - "locationDetails": null, + "nylasPageId": "001d31e8-6e6b-458b-be1c-85349187c7d3", + "availableTime": [ + { + "start": "09:00", + "end": "17:00", + "days": ["M", "W"] + } + ], + "nylasCalendarId": "785735", + "hostTimezone": "Europe/London", + "guestTimezone": null, + "hostUserId": "c0c6e737-1f1e-457e-b146-15a05752e652", + "nylasPageSlug": "tc-taas-interview-9efd72c3-1dc7-4ce2-9869-8cca81d0adeb", "duration": null, "round": 1, "startTimestamp": null, "endTimestamp": null, - "hostName": null, - "hostEmail": "interviewhost@tc.com", - "guestNames": ["guest name1", "guest name2"], - "guestEmails": ["guest1@tc.com", "guest2@tc.com"], "status": "Completed", - "rescheduleUrl": null, "createdBy": "57646ff9-1cd3-4d3c-88ba-eb09a395366c", "updatedBy": null, "createdAt": "2021-05-09T21:21:17.346Z", diff --git a/data/notification-email-templates/taas.notification.candidates-available-for-review.html b/data/notification-email-templates/taas.notification.candidates-available-for-review.html new file mode 100644 index 00000000..896b7578 --- /dev/null +++ b/data/notification-email-templates/taas.notification.candidates-available-for-review.html @@ -0,0 +1,274 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Your Candidates
+
+ + + + + + + + + +
IMG + Here are Your Candidates Awaiting Review + +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ You’ve matched with talent! Use the link below to review your candidates. You can schedule an interview if you want to move forward, or decline if they’re not a match. +
+
+ + + + + + + + {{#each teamJobs}} + + + + + + + {{/each}} +
Job titleNo of resource bookingsCandidatesReview
+ {{this.title}} + {{this.nResourceBookings}} +
    + {{#each this.jobCandidates}} +
  • {{this.handle}}
  • + {{/each}} +
+
+ Link +
+ +
+ Please, review your candidates. + +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-awaits-resolution.html b/data/notification-email-templates/taas.notification.interview-awaits-resolution.html new file mode 100644 index 00000000..cdb76f1f --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-awaits-resolution.html @@ -0,0 +1,269 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Next Steps with Your Candidate
+
+ + + + + + + + + +
IMG + Interview Complete, What To Do Next +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Thanks for taking the time to interview your candidate. We hope it went well and that they are a perfect fit. Now it’s time to take action: +
+
+ Use the link below to Accept, Decline, or schedule another interview. Don’t wait—Topcoder talent is in high-demand: +
+
+ + + + + + + + + + + + + +
Job titleCandidate HandleDate and TimeInterviews
+ {{this.jobTitle}} + {{this.handle}}{{this.startTime}} + Link
+ +
+ Take action on your candidates +
+
+ Any issues with this interview? Please contact us here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-cancelled-guest.html b/data/notification-email-templates/taas.notification.interview-cancelled-guest.html new file mode 100644 index 00000000..bfcd7dd8 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-cancelled-guest.html @@ -0,0 +1,250 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{this.subject}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + Hi {{this.guest}}, +
+ Your interview with {{this.host}} on {{this.start}} has been cancelled +
+
+
Job: {{this.jobTitle}}
+
Interviewer: {{this.host}}
+
+
+ Need help? Reply to this email or contact Ops + here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-cancelled-host.html b/data/notification-email-templates/taas.notification.interview-cancelled-host.html new file mode 100644 index 00000000..1a171b4a --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-cancelled-host.html @@ -0,0 +1,250 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{this.subject}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + Hi {{this.host}}, +
+ Your interview with {{this.guest}} on {{this.start}} has been cancelled +
+
+
Job: {{this.jobTitle}}
+
Interviewee: {{this.guest}}
+
+
+ Need help? Reply to this email or contact Ops + here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-coming-up-guest.html b/data/notification-email-templates/taas.notification.interview-coming-up-guest.html new file mode 100644 index 00000000..a1f04758 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-coming-up-guest.html @@ -0,0 +1,256 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Reminder: Interview with Client
+
+ + + + + + + + + +
IMG + You Have an Upcoming Interview +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ You have an interview coming up for a Topcoder gig! +
+
+
Job: {{this.jobTitle}}
+
Interviewer: {{this.host}}
+
Zoom link: + zoom link +
+
Start: {{this.start}}
+
End: {{this.end}}
+
Timezone: {{this.guestTimezone}}
+
+ If you’re signed in to your Topcoder account, you can also find this information on the My Gigs Applications page. + +
+ +

Good luck at the interview!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-coming-up-host.html b/data/notification-email-templates/taas.notification.interview-coming-up-host.html new file mode 100644 index 00000000..f7cea7c0 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-coming-up-host.html @@ -0,0 +1,255 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Interview Coming Up
+
+ + + + + + + + + +
IMG + Reminder: You Have an Upcoming Interview +
+
+ + + + + + +
+ + + + + + + + +
+ +
+ Ohhh the butterflies before a first date. Just kidding, this is totally professional. But meeting someone who could potentially make your life a lot easier is very exciting. +
+
+ This is your reminder that you have an interview coming up with an awesome Topcoder freelance candidate. Click the link below to review their resume and profile before the big event. +
+
+
Job: {{this.jobTitle}}
+
Interviewee: {{this.guest}}
+
Zoom link: + zoom link +
+
Start: {{this.start}}
+
End: {{this.end}}
+
Timezone: {{this.hostTimezone}}
+
+ Candidate resume and profile +

Can’t wait to hear how it goes,
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-expired-guest.html b/data/notification-email-templates/taas.notification.interview-expired-guest.html new file mode 100644 index 00000000..9be1e912 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-expired-guest.html @@ -0,0 +1,252 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Your interview has expired
+
+ + + + + + + + + +
IMG + Interview Invitation Expired: {{this.duration}} minutes tech interview with {{this.guestFullName}} for {{this.jobTitle}} is requested by the Customer +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ The interview has become unavailable because you didn't select time before expired +
+
+
Job Title: {{this.jobTitle}}
+
Interview Length: {{this.duration}} minutes
+
Interview Round: {{this.interviewRound}}
+
Interviewee: {{this.guestFullName}}
+
Interviewer: {{this.hostFullName}}
+ + +
+ Need help? Please contact us here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-expired-host.html b/data/notification-email-templates/taas.notification.interview-expired-host.html new file mode 100644 index 00000000..2ca40dba --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-expired-host.html @@ -0,0 +1,252 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Interview expired notification
+
+ + + + + + + + + +
IMG + Candidate Didn't Schedule Interview: {{this.duration}} minutes tech interview with {{this.guestFullName}} for {{this.jobTitle}} is requested by the Customer +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ The interview has become unavailable because the candidate didn't select time before expired +
+
+ +
Job Title: {{this.jobTitle}}
+
Interview Length: {{this.duration}} minutes
+
Interview Round: {{this.interviewRound}}
+
Interviewee: {{this.guestFullName}}
+
Interviewer: {{this.hostFullName}}
+ +
+ Propose a new interview or contact Ops here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-invitation.html b/data/notification-email-templates/taas.notification.interview-invitation.html new file mode 100644 index 00000000..da535587 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-invitation.html @@ -0,0 +1,253 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Schedule Your Interview
+
+ + + + + + + + + +
IMG + {{this.duration}} minutes tech interview with {{this.guestFullName}} for {{this.jobTitle}} is requested by the Customer +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Interview Details. +
+
+
Job Title: {{this.jobTitle}}
+
Interview Length: {{this.duration}} minutes
+
Interview Round: {{this.interviewRound}}
+
Interviewee: {{this.guestFullName}}
+
Interviewer: {{this.hostFullName}}
+
+ Select Interview Time +
+
+ Need help? Please contact us here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-link-for-guest.html b/data/notification-email-templates/taas.notification.interview-link-for-guest.html new file mode 100644 index 00000000..9dd4c89f --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-link-for-guest.html @@ -0,0 +1,257 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{this.subject}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + Hi {{this.guest}}, +
+ You're meeting with {{this.host}} on {{this.start}}. +
+
+
Job: {{this.jobTitle}}
+
Interviewer: {{this.host}}
+
Zoom link: + zoom link +
+
Start: {{this.start}}
+
End: {{this.end}}
+
Timezone: {{this.guestTimezone}}
+
+ Cancel | Reschedule +

+ Need help? Reply to this email or contact Ops + here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-link-for-host.html b/data/notification-email-templates/taas.notification.interview-link-for-host.html new file mode 100644 index 00000000..52abb4fb --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-link-for-host.html @@ -0,0 +1,257 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{this.subject}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + Hi {{this.host}}, +
+ You're meeting with {{this.guest}} on {{this.start}}. +
+
+
Job: {{this.jobTitle}}
+
Interviewee: {{this.guest}}
+
Zoom link: + zoom link +
+
Start: {{this.start}}
+
End: {{this.end}}
+
Timezone: {{this.hostTimezone}}
+
+ Cancel | Reschedule +

+ Need help? Reply to this email or contact Ops + here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-rescheduled-guest.html b/data/notification-email-templates/taas.notification.interview-rescheduled-guest.html new file mode 100644 index 00000000..ca5f815a --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-rescheduled-guest.html @@ -0,0 +1,257 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{this.subject}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + Hi {{this.guest}}, +
+ Your interview with {{this.host}} on {{this.oldStart}} has been rescheduled to {{this.start}} +
+
+
Job: {{this.jobTitle}}
+
Interviewer: {{this.host}}
+
Zoom link: + zoom link +
+
Start: {{this.start}}
+
End: {{this.end}}
+
Timezone: {{this.guestTimezone}}
+
+ Cancel | Reschedule +

+ Need help? Reply to this email or contact Ops + here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-rescheduled-host.html b/data/notification-email-templates/taas.notification.interview-rescheduled-host.html new file mode 100644 index 00000000..5527ca88 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-rescheduled-host.html @@ -0,0 +1,257 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{this.subject}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + Hi {{this.host}}, +
+ Your interview with {{this.guest}} on {{this.oldStart}} has been rescheduled to {{this.start}} +
+
+
Job: {{this.jobTitle}}
+
Interviewee: {{this.guest}}
+
Zoom link: + zoom link +
+
Start: {{this.start}}
+
End: {{this.end}}
+
Timezone: {{this.hostTimezone}}
+
+ Cancel | Reschedule +

+ Need help? Reply to this email or contact Ops + here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interview-schedule-reminder.html b/data/notification-email-templates/taas.notification.interview-schedule-reminder.html new file mode 100644 index 00000000..44dffe5d --- /dev/null +++ b/data/notification-email-templates/taas.notification.interview-schedule-reminder.html @@ -0,0 +1,254 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Interview Schedule Reminder
+
+ + + + + + + + + +
IMG + Reminder: {{this.duration}} minutes tech interview with {{this.guestFullName}} for {{this.jobTitle}} is requested by the Customer +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ This is a reminder. The customer is ready to interview you. Please schedule now below. +
+
+
Job Title: {{this.jobTitle}}
+
Interview Length: {{this.duration}} minutes
+
Interview Round: {{this.interviewRound}}
+
Interviewee: {{this.guestFullName}}
+
Interviewer: {{this.hostFullName}}
+ +
+ Select Interview Time +
+
+ Need help? Please contact us here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.interviews-overlapping.html b/data/notification-email-templates/taas.notification.interviews-overlapping.html new file mode 100644 index 00000000..14d9ec44 --- /dev/null +++ b/data/notification-email-templates/taas.notification.interviews-overlapping.html @@ -0,0 +1,262 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{description}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + {{#each interviews}} + + + + + + + + {{/each}} +
Team NameJob TitleJob CandidateInterview Start DateInterview End Date
{{this.teamName}}{{this.jobTitle}}{{this.candidateUserHandle}}{{this.startTime}}{{this.endTime}}
+ +
+ If you have any questions about this process or if you encounter any issues coordinating your availability, you may reply to this email or send a separate email to our Gig Work operations team. + +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.job-candidate-resume-viewed.html b/data/notification-email-templates/taas.notification.job-candidate-resume-viewed.html new file mode 100644 index 00000000..9dfda6ea --- /dev/null +++ b/data/notification-email-templates/taas.notification.job-candidate-resume-viewed.html @@ -0,0 +1,249 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Update on Your Application
+
+ + + + + + + + + +
IMG + Client Has Viewed Your Profile +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Thanks for applying for a Topcoder Gig. This is an update to let you know that the client has viewed your profile. We will notify you about next steps. + +
+
+ To check the status of all your Gig Work applications, log in to your Topcoder account and head to My Gigs → Open Applications. + +
+
+ +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.job-candidate-selected.html b/data/notification-email-templates/taas.notification.job-candidate-selected.html new file mode 100644 index 00000000..86dc733c --- /dev/null +++ b/data/notification-email-templates/taas.notification.job-candidate-selected.html @@ -0,0 +1,260 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Topcoder Gig Work
+
+ + + + + + + + + +
IMG + {{description}} +
+
+ + + + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
Team NameJob TitleJob Start DateJob DurationJob Candidate
{{teamName}}{{jobTitle}}{{jobStartDate}}{{jobDuration}}{{userHandle}}
+ +
+ If you have any questions about this process or if you encounter any issues coordinating your availability, you may reply to this email or send a separate email to our Gig Work operations team. + +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.job-created.html b/data/notification-email-templates/taas.notification.job-created.html new file mode 100644 index 00000000..d72610f2 --- /dev/null +++ b/data/notification-email-templates/taas.notification.job-created.html @@ -0,0 +1,260 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Update
+
+ + + + + + + + + +
IMG + New Job Added to Your Team +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ We’ve received your request for a new role on your team. We’ll notify you when you have a new candidate to review. You can add more roles to your team any time. +
+
+ + + + + + + + + + + + + +
Team NameJob TitleJob Start DateJob Duration
{{teamName}}{{jobTitle}}{{jobStartDate}}{{jobDuration}}
+ +
+ +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.post-interview-action-required.html b/data/notification-email-templates/taas.notification.post-interview-action-required.html new file mode 100644 index 00000000..f851cd89 --- /dev/null +++ b/data/notification-email-templates/taas.notification.post-interview-action-required.html @@ -0,0 +1,268 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Reminder: Ghosting Is Not Cool
+
+ + + + + + + + + +
IMG + Take Action on This Candidate +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Use the link below to Accept, Decline, or schedule another interview with your candidate. This person might have an offer on another gig, and is awaiting your response to make a decision. Please do this now: +
+
+ + + + + + + + {{#each teamInterviews}} + + + + + + + {{/each}} +
Job titleHandleDate and TimeInterviews
+ {{this.jobTitle}} + {{this.handle}}{{this.startTime}} + Link
+ +
+ Please, take action on your candidates. +
+
+ Any issues? Please contact us here. +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.resource-booking-expiration.html b/data/notification-email-templates/taas.notification.resource-booking-expiration.html new file mode 100644 index 00000000..a973af00 --- /dev/null +++ b/data/notification-email-templates/taas.notification.resource-booking-expiration.html @@ -0,0 +1,267 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Reminder
+
+ + + + + + + + + +
IMG + Work End Date Approaching +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Good things can’t last forever, and one or more of your freelancer’s work End Date is approaching. Want to continue working with them? Request an extension here by clicking on the Actions menu and selecting “Request an Extension”. +
+
+ To check the end date for any talent on your team, log in to your account and head to your Teams page. +
+
+ + + + + + + {{#each teamResourceBookings}} + + + + + + {{/each}} +
Job titleResource Bookings HandleEnd Date
+ {{this.jobTitle}} + + {{this.handle}} + {{this.endDate}}
+ +
+ +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.resource-booking-placed.html b/data/notification-email-templates/taas.notification.resource-booking-placed.html new file mode 100644 index 00000000..28640992 --- /dev/null +++ b/data/notification-email-templates/taas.notification.resource-booking-placed.html @@ -0,0 +1,258 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Get Excited
+
+ + + + + + + + + +
IMG + Your Topcoder Talent is Confirmed +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Pop the metaphorical champagne. Your Topcoder talent is officially confirmed! This person is super excited to work with you. Here are the details. +
+
+ + + + + + + + + + + +
Team NameJob TitleResource Booking Handle
{{teamName}}{{jobTitle}}{{userHandle}}
+ +
+ +

Thanks!
+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notification-email-templates/taas.notification.team-created.html b/data/notification-email-templates/taas.notification.team-created.html new file mode 100644 index 00000000..8ecfd7b1 --- /dev/null +++ b/data/notification-email-templates/taas.notification.team-created.html @@ -0,0 +1,260 @@ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + +
IMG +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ Your Request is Confirmed
+
+ + + + + + + + + +
IMG + Talent Request Confirmed +
+
+ + + + + + +
+ + + + + + + + + +
+ +
+ Congratulations! You’ve successfully submitted your talent request to Topcoder. We’ll notify you when you have a new candidate to review. You can add more roles to your team at any time. +
+
+ + + + + + + {{#each jobList}} + + + + + + {{/each}} +
Job TitleJob Start DateJob Duration
{{this.title}}{{this.startDate}}{{this.duration}}
+ +
+ Thanks for your request. We look forward to bringing you awesome freelance talent. +

+ The Topcoder Team +

+
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ 201 S Capitol Ave #1100
+ Indianapolis, IN 46225 United States
+
+ ●●●
+
+ Topcoder System Information: +
+ InterviewType: {{xai_template}}
+
+ + + + + + +
+
+
diff --git a/data/notifications-email-template.html b/data/notifications-email-template.html deleted file mode 100644 index f0da558d..00000000 --- a/data/notifications-email-template.html +++ /dev/null @@ -1,492 +0,0 @@ -
- - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
- - - - - - - - -
IMG -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -
- Topcoder Gig Work
-
- - - - - - - - - -
IMG - {{description}} -
-
- - - - - - -
- - - - - - - - -
- - {{#if notificationType.candidatesAvailableForReview}} - - - - - - - - {{#each teamJobs}} - - - - - - - {{/each}} -
Job titleNo of resource bookingsCandidatesReview
- {{this.title}} - {{this.nResourceBookings}} -
    - {{#each this.jobCandidates}} -
  • {{this.handle}}
  • - {{/each}} -
-
- Link -
- {{/if}} - - {{#if notificationType.interviewComingUpForHost}} - - - - - - - - - - - - - - - -
Job titleCandidate HandleInterviewsAttendeesDate and Time
- {{this.jobTitle}} - {{this.handle}} - Link -
    - {{#each this.attendees}} -
  • {{this}}
  • - {{/each}} -
-
{{this.startTime}}
- {{/if}} - - {{#if notificationType.interviewComingUpForGuest}} - - - - - - - - - - - -
Job titleDate and TimeInterviews
- {{this.jobTitle}} - {{this.startTime}} - Link
- {{/if}} - - {{#if notificationType.interviewCompleted}} - - - - - - - - - - - - - - - -
Job titleCandidate HandleDate and TimeAttendeesInterviews
- {{this.jobTitle}} - {{this.handle}}{{this.startTime}} -
    - {{#each this.attendees}} -
  • {{this}}
  • - {{/each}} -
-
- Link
- {{/if}} - - {{#if notificationType.postInterviewCandidateAction}} - - - - - - - - - {{#each teamInterviews}} - - - - - - - - {{/each}} -
Job titleHandleDate and TimeAttendeesInterviews
- {{this.jobTitle}} - {{this.handle}}{{this.startTime}} -
    - {{#each this.attendees}} -
  • {{this}}
  • - {{/each}} -
-
- Link
- {{/if}} - - {{#if notificationType.upcomingResourceBookingExpiration}} - Team Name: - {{teamName}} - - - - - - - {{#each teamResourceBookings}} - - - - - - {{/each}} -
Job titleResource Bookings HandleEnd Date
- {{this.jobTitle}} - - {{this.handle}} - {{this.endDate}}
- {{/if}} - - {{#if notificationType.jobCandidateResumeViewed}} - Hi {{jobCandidateUserHandle}}.

- - Your resume for the job "{{jobName}}" has been viewed by the client.
- {{/if}} - - {{#if notificationType.newTeamCreated}} - Team: - {{teamName}} - - - - - - - {{#each jobList}} - - - - - - {{/each}} -
Job TitleJob Start DateJob Duration
{{this.title}}{{this.startDate}}{{this.duration}}
- {{/if}} - {{#if notificationType.newJobCreated}} - - - - - - - - - - - - - -
Team NameJob TitleJob Start DateJob Duration
{{teamName}}{{jobTitle}}{{jobStartDate}}{{jobDuration}}
- {{/if}} - {{#if notificationType.overlappingInterview}} - - - - - - - - - {{#each interviews}} - - - - - - - - {{/each}} -
Team NameJob TitleJob CandidateInterview Start DateInterview End Date
{{this.teamName}}{{this.jobTitle}}{{this.candidateUserHandle}}{{this.startTime}}{{this.endTime}}
- {{/if}} - {{#if notificationType.candidateSelected}} - - - - - - - - - - - - - - - -
Team NameJob TitleJob Start DateJob DurationJob Candidate
{{teamName}}{{jobTitle}}{{jobStartDate}}{{jobDuration}}{{userHandle}}
- {{/if}} - {{#if notificationType.resourceBookingPlaced}} - - - - - - - - - - - - - - - -
Team NameJob TitleResource Booking HandleResource Booking Start DateResource Booking End Date
{{teamName}}{{jobTitle}}{{userHandle}}{{startDate}}{{endDate}}
- {{/if}} - -
- If you have any questions about this process or if you encounter any issues coordinating your availability, you may reply to this email or send a separate email to our Gig Work operations team. - -

Thanks!
- The Topcoder Team -

-
-
-
- - - - - - -
-
- - - - - - -
-
-
- - - - - - -
-
- - - - - - - - - - - - - - - - - -
- - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- 201 S Capitol Ave #1100
- Indianapolis, IN 46225 United States
-
- ●●●
-
- Topcoder System Information: -
- InterviewType: {{xai_template}}
-
- - - - - - -
-
-
diff --git a/docs/Topcoder-bookings-api.postman_collection.json b/docs/Topcoder-bookings-api.postman_collection.json index 436c95b9..5cf64479 100644 --- a/docs/Topcoder-bookings-api.postman_collection.json +++ b/docs/Topcoder-bookings-api.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "d53e9443-d401-4795-98c6-2d349f7f0313", + "_postman_id": "db078688-3b62-457d-8f7a-c680a6ef3d42", "name": "Topcoder-bookings-api", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, @@ -3755,58 +3755,6 @@ } }, "response": [] - }, - { - "name": "Create completed interview", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200)\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"completedInterviewJobCandidateId\", response.jobCandidateId);\r", - " pm.environment.set(\"completedInterviewRound\", response.round);\r", - " }\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"status\": \"Completed\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "requestInterview" - ] - } - }, - "response": [] } ] }, @@ -3823,6 +3771,7 @@ " const response = pm.response.json()\r", " pm.environment.set(\"interviewId\", response.id);\r", " pm.environment.set(\"interviewRound\", response.round);\r", + " pm.environment.set(\"userIdWithUserMeetingSettings\", response.hostUserId);\r", " }\r", "});" ], @@ -3841,7 +3790,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"calendarEventId\": \"dummyId\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"guestEmails\": [\"attendee1@yopmail.com\", \"attendee2@yopmail.com\"],\r\n \"status\": \"Scheduling\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"U\",\r\n \"M\",\r\n \"T\",\r\n \"W\",\r\n \"T\",\r\n \"F\",\r\n \"S\"\r\n ],\r\n \"start\": \"01:00\",\r\n \"end\": \"23:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -3893,7 +3842,59 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"calendarEventId\": \"dummyId\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"status\": \"Scheduling\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "requestInterview" + ] + } + }, + "response": [] + }, + { + "name": "Request 3rd interview - should allow", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", + " const response = pm.response.json();\r", + " const lastRound = pm.environment.get(\"interviewRound\");\r", + " pm.expect(response.round).to.eq(lastRound + 1);\r", + " pm.environment.set(\"interviewRound\", response.round);\r", + " pm.environment.set(\"interviewId\", response.id);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -3942,7 +3943,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -3964,19 +3965,16 @@ "response": [] }, { - "name": "Request interview without status - should take default status", + "name": "Request interview without duration - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200)\r", - " if(pm.response.status === \"OK\"){\r", - " const response = pm.response.json()\r", - " pm.environment.set(\"interviewRound\", response.round);\r", - " pm.expect(response.status).to.eq(\"Scheduling\")\r", - " }\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.duration\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -3994,7 +3992,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4016,7 +4014,7 @@ "response": [] }, { - "name": "Request interview with invalid status", + "name": "Request interview without hostTimezone - should fail Copy", "event": [ { "listen": "test", @@ -4025,7 +4023,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"interview.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.hostTimezone\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -4043,7 +4041,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"status\": \"xxxx\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4051,13 +4049,13 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{jobCandidateId}}", + "{{jobCandidateId_2}}", "requestInterview" ] } @@ -4065,17 +4063,16 @@ "response": [] }, { - "name": "Request interview with guestEmails", + "name": "Request interview without availableTime - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.guestEmails[0]).to.eq(\"attendee1@yopmail.com\")\r", - " pm.expect(response.guestEmails[1]).to.eq(\"attendee2@yopmail.com\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.availableTime\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -4093,7 +4090,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"guestEmails\": [\"attendee1@yopmail.com\", \"attendee2@yopmail.com\"]\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\"\r\n}", "options": { "raw": { "language": "json" @@ -4115,7 +4112,7 @@ "response": [] }, { - "name": "Request interview with invalid guestEmails", + "name": "Request interview with empty availableTime - should fail", "event": [ { "listen": "test", @@ -4124,7 +4121,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"interview.guestEmails\\\" must be an array\")\r", + " pm.expect(response.message).to.eq(\"\\\"interview.availableTime\\\" must contain at least 1 items\")\r", "});" ], "type": "text/javascript" @@ -4142,7 +4139,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"guestEmails\": \"asddd\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": []\r\n}", "options": { "raw": { "language": "json" @@ -4150,13 +4147,13 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{jobCandidateId}}", + "{{jobCandidateId_2}}", "requestInterview" ] } @@ -4164,7 +4161,7 @@ "response": [] }, { - "name": "Request interview with invalid guest email", + "name": "Request interview without availableTime.start - should fail", "event": [ { "listen": "test", @@ -4173,7 +4170,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"interview.guestEmails[0]\\\" must be a valid email\")\r", + " pm.expect(response.message).to.contain(\".start\\\" is required\")\r", "});" ], "type": "text/javascript" @@ -4191,7 +4188,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"guestEmails\": [\"asdas\"]\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4199,13 +4196,160 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{jobCandidateId}}", + "{{jobCandidateId_2}}", + "requestInterview" + ] + } + }, + "response": [] + }, + { + "name": "Request interview without availableTime.end - should fail", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.contain(\".end\\\" is required\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"10:00\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId_2}}", + "requestInterview" + ] + } + }, + "response": [] + }, + { + "name": "Request interview with invalid availableTime.days - should fail", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"\\\"interview.availableTime[0].days[0]\\\" must be one of [M, T, W, R, F, S, U]\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"L\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId_2}}", + "requestInterview" + ] + } + }, + "response": [] + }, + { + "name": "Request interview with too many availableTime.days - should fail", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.contain(\".days\\\" must contain less than or equal to 7 items\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\", \"R\", \"F\", \"S\", \"U\", \"F\", \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId_2}}", "requestInterview" ] } @@ -4240,7 +4384,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"round\": 1\r\n}", + "raw": "{\r\n \"round\": 1,\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4289,7 +4433,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\",\r\n \"startTimestamp\": \"2021-04-17\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2021-04-17\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4311,16 +4455,16 @@ "response": [] }, { - "name": "Request interview without templateUrl - should fail", + "name": "Request interview with non-existing jobCandidate", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(404);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"interview.templateUrl\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"The job candidate with id=9105f597-f9d5-49c0-9cbf-9a0cbda47260 doesn't exist.\")\r", "});" ], "type": "text/javascript" @@ -4338,7 +4482,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"Scheduling\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4346,13 +4490,13 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", + "raw": "{{URL}}/jobCandidates/9105f597-f9d5-49c0-9cbf-9a0cbda47260/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{jobCandidateId}}", + "9105f597-f9d5-49c0-9cbf-9a0cbda47260", "requestInterview" ] } @@ -4360,7 +4504,7 @@ "response": [] }, { - "name": "Request interview with invalid templateUrl", + "name": "Request interview with non-existing userId in token", "event": [ { "listen": "test", @@ -4369,56 +4513,7 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"interview.templateUrl\\\" must be one of [interview-30, interview-60]\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"asdas\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/requestInterview", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "requestInterview" - ] - } - }, - "response": [] - }, - { - "name": "Request interview with non-existing jobCandidate", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 404', function () {\r", - " pm.response.to.have.status(404);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"The job candidate with id=9105f597-f9d5-49c0-9cbf-9a0cbda47260 doesn't exist.\")\r", + " pm.expect(response.message).to.eq(\"Bad Request\")\r", "});" ], "type": "text/javascript" @@ -4430,13 +4525,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_userId_not_exist}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4444,13 +4539,13 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/9105f597-f9d5-49c0-9cbf-9a0cbda47260/requestInterview", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "9105f597-f9d5-49c0-9cbf-9a0cbda47260", + "{{jobCandidateId_2}}", "requestInterview" ] } @@ -4458,16 +4553,14 @@ "response": [] }, { - "name": "Request interview with non-existing userId in token", + "name": "Request interview with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Bad Request\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -4479,13 +4572,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_userId_not_exist}}", + "value": "Bearer {{token_administrator}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4493,13 +4586,13 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId_2}}/requestInterview", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_3}}/requestInterview", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{jobCandidateId_2}}", + "{{jobCandidateId_3}}", "requestInterview" ] } @@ -4507,7 +4600,7 @@ "response": [] }, { - "name": "Request interview with administrator", + "name": "Request interview with booking manager", "event": [ { "listen": "test", @@ -4526,13 +4619,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_administrator}}", + "value": "Bearer {{token_bookingManager}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4554,14 +4647,16 @@ "response": [] }, { - "name": "Request interview with booking manager", + "name": "Request interview with m2m (all interview scope) and no hostUserId - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"interview.hostUserId undefined is required and must be a valid uuid\")\r", "});" ], "type": "text/javascript" @@ -4573,13 +4668,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_m2m_all_interviews}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4626,7 +4721,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"hostUserId\": \"57646ff9-1cd3-4d3c-88ba-eb09a395366c\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4673,7 +4768,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"hostUserId\": \"57646ff9-1cd3-4d3c-88ba-eb09a395366c\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4722,7 +4817,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"hostUserId\": \"57646ff9-1cd3-4d3c-88ba-eb09a395366c\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4771,7 +4866,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"hostUserId\": \"57646ff9-1cd3-4d3c-88ba-eb09a395366c\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4820,7 +4915,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4869,7 +4964,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4918,7 +5013,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -4961,7 +5056,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -5010,7 +5105,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"interview-30\",\r\n \"hostEmail\": \"testcustomer@yopmail.com\"\r\n}", + "raw": "{\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"T\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -5781,7 +5876,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"dummyIdXX\",\r\n \"xaiId\": \"0edc1751-f4ca-4e8e-908a-95f6560311ab\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -5789,13 +5884,13 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId_4}}/updateInterview/{{interviewRound}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId_3}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{jobCandidateId_4}}", + "{{jobCandidateId_3}}", "updateInterview", "{{interviewRound}}" ] @@ -5813,7 +5908,8 @@ "pm.test('Status code is 400', function () {\r", " pm.response.to.have.status(400);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data\\\" must have at least 1 key\")\r", + " //since now we have required fields inside the object, their validations take precedence\r", + " pm.expect(response.message).to.be.oneOf([\"\\\"data\\\" must have at least 1 key\", \"\\\"data.duration\\\" is required\"])\r", "});" ], "type": "text/javascript" @@ -5881,7 +5977,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"startTimestamp\": \"xxx\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"xxx\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/Rome\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -5931,7 +6027,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"startTimestamp\": \"2021-04-01\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2021-04-01\",\r\n \"duration\": 30,\r\n \"hostTimezone\": \"Europe/Rome\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n\r\n}", "options": { "raw": { "language": "json" @@ -5954,16 +6050,14 @@ "response": [] }, { - "name": "Update interview with invalid status", + "name": "Update interview with booking manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.status\\\" must be one of [Scheduling, Scheduled, Requested for reschedule, Rescheduled, Completed, Cancelled]\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -5981,7 +6075,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"status\": \"xxx\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6004,16 +6098,14 @@ "response": [] }, { - "name": "Update interview with invalid templateUrl", + "name": "Update interview with administrator", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.templateUrl\\\" must be one of [interview-30, interview-60]\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -6025,13 +6117,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_administrator}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"templateUrl\": \"xxx\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6054,16 +6146,14 @@ "response": [] }, { - "name": "Update interview status to Scheduled without calendarEventId", + "name": "Update interview with m2m (all interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.calendarEventId\\\" is required\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -6075,13 +6165,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_m2m_all_interviews}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"startTimestamp\": \"2030-12-12\",\r\n \"status\": \"Scheduled\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6104,16 +6194,14 @@ "response": [] }, { - "name": "Update interview status to Scheduled without startTimestamp", + "name": "Update interview with m2m (update interview scope)", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" is required\")\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200);\r", "});" ], "type": "text/javascript" @@ -6125,13 +6213,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_m2m_update_interviews}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\",\r\n \"status\": \"Scheduled\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6154,16 +6242,16 @@ "response": [] }, { - "name": "Update interview status to Rescheduled without calendarEventId", + "name": "Update interview with m2m (read interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.calendarEventId\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6175,13 +6263,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_m2m_read_interviews}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"startTimestamp\": \"2030-12-12\",\r\n \"status\": \"Rescheduled\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6204,16 +6292,16 @@ "response": [] }, { - "name": "Update interview status to Rescheduled without startTimestamp", + "name": "Update interview with m2m (create interview scope) - should fail", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"\\\"data.startTimestamp\\\" is required\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6225,13 +6313,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_m2m_create_interviews}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\",\r\n \"status\": \"Rescheduled\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6254,66 +6342,16 @@ "response": [] }, { - "name": "Update Completed interview without status", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Only the \\\"status\\\" can be updated for Completed interviews.\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{completedInterviewJobCandidateId}}", - "updateInterview", - "{{completedInterviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Completed interview with additional fields", + "name": "Update interview with connect manager", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 400', function () {\r", - " pm.response.to.have.status(400);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Only the \\\"status\\\" can be updated for Completed interviews.\")\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6325,13 +6363,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\",\r\n \"status\": \"Scheduling\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6339,79 +6377,31 @@ } }, "url": { - "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", "host": [ "{{URL}}" ], "path": [ "jobCandidates", - "{{completedInterviewJobCandidateId}}", + "{{jobCandidateId}}", "updateInterview", - "{{completedInterviewRound}}" + "{{interviewRound}}" ] } }, "response": [] }, { - "name": "Update Completed interview with only status", + "name": "Update interview with connect user", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", " const response = pm.response.json()\r", - " pm.expect(response.status).to.eq(\"Scheduling\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"status\": \"Scheduling\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{completedInterviewJobCandidateId}}/updateInterview/{{completedInterviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{completedInterviewJobCandidateId}}", - "updateInterview", - "{{completedInterviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with booking manager", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6423,13 +6413,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", + "value": "Bearer {{token_connectUser}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6452,14 +6442,16 @@ "response": [] }, { - "name": "Update interview with administrator", + "name": "Update interview with member", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", "});" ], "type": "text/javascript" @@ -6471,359 +6463,13 @@ "header": [ { "key": "Authorization", - "value": "Bearer {{token_administrator}}", + "value": "Bearer {{token_member}}", "type": "text" } ], "body": { "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with m2m (all interview scope)", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_m2m_all_interviews}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with m2m (update interview scope)", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_m2m_update_interviews}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with m2m (read interview scope) - should fail", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_m2m_read_interviews}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with m2m (create interview scope) - should fail", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_m2m_create_interviews}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with connect manager", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with connect user", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_connectUser}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", - "host": [ - "{{URL}}" - ], - "path": [ - "jobCandidates", - "{{jobCandidateId}}", - "updateInterview", - "{{interviewRound}}" - ] - } - }, - "response": [] - }, - { - "name": "Update interview with member", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", - " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_member}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"calendarEventId\": \"sdsds\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6867,7 +6513,7 @@ "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6917,7 +6563,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"customMessage\": \"sdsds\"\r\n}", + "raw": "{\r\n \"duration\": 60,\r\n \"hostTimezone\": \"Europe/London\",\r\n \"availableTime\": [\r\n {\r\n \"days\": [\r\n \"M\", \"T\", \"W\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"10:30\"\r\n },\r\n {\r\n \"days\": [\r\n \"F\"\r\n ],\r\n \"start\": \"09:00\",\r\n \"end\": \"14:00\"\r\n }\r\n ]\r\n}", "options": { "raw": { "language": "json" @@ -6939,86 +6585,6 @@ }, "response": [] }, - { - "name": "Get interview by xaiId", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200)\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "url": { - "raw": "{{URL}}/getInterview/0edc1751-f4ca-4e8e-908a-95f6560311ab", - "host": [ - "{{URL}}" - ], - "path": [ - "getInterview", - "0edc1751-f4ca-4e8e-908a-95f6560311ab" - ] - } - }, - "response": [] - }, - { - "name": "Get interview by xaiId fromDb", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200)\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "url": { - "raw": "{{URL}}/getInterview/0edc1751-f4ca-4e8e-908a-95f6560311ab?fromDb=true", - "host": [ - "{{URL}}" - ], - "path": [ - "getInterview", - "0edc1751-f4ca-4e8e-908a-95f6560311ab" - ], - "query": [ - { - "key": "fromDb", - "value": "true" - } - ] - } - }, - "response": [] - }, { "name": "Update interview by id", "event": [ @@ -7045,7 +6611,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"xaiId\": \"0edc1751-f4ca-4e8e-908a-95f6560311ab\"\r\n}", + "raw": "{\r\n \"startTimestamp\": \"2021-11-30T16:15:00.000Z\",\r\n \"status\": \"Scheduled\"\r\n}", "options": { "raw": { "language": "json" @@ -7065,52 +6631,6 @@ }, "response": [] }, - { - "name": "Update interview by xaiId", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test('Status code is 200', function () {\r", - " pm.response.to.have.status(200)\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PATCH", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_bookingManager}}", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"xaiId\": \"0edc1751-f4ca-4e8e-908a-95f6560311ab\",\r\n \"calendarEventId\": \"test\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{URL}}/updateInterview/0edc1751-f4ca-4e8e-908a-95f6560311ab", - "host": [ - "{{URL}}" - ], - "path": [ - "updateInterview", - "0edc1751-f4ca-4e8e-908a-95f6560311ab" - ] - } - }, - "response": [] - }, { "name": "Search interviews", "event": [ @@ -8035,16 +7555,83 @@ "response": [] }, { - "name": "Search interviews with member", + "name": "Search interviews with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_member}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "interviews" + ], + "query": [ + { + "key": "sortBy", + "value": "createdAt", + "disabled": true + }, + { + "key": "sortOrder", + "value": "desc", + "disabled": true + }, + { + "key": "createdAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "updatedAt", + "value": "2021-04-13T20:28:37.954Z", + "disabled": true + }, + { + "key": "status", + "value": "Scheduling", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Search interviews without token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"No token provided.\")\r", "});" ], "type": "text/javascript" @@ -8053,13 +7640,7 @@ ], "request": { "method": "GET", - "header": [ - { - "key": "Authorization", - "value": "Bearer {{token_member}}", - "type": "text" - } - ], + "header": [], "url": { "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ @@ -8069,40 +7650,13 @@ "jobCandidates", "{{jobCandidateId}}", "interviews" - ], - "query": [ - { - "key": "sortBy", - "value": "createdAt", - "disabled": true - }, - { - "key": "sortOrder", - "value": "desc", - "disabled": true - }, - { - "key": "createdAt", - "value": "2021-04-13T20:28:37.954Z", - "disabled": true - }, - { - "key": "updatedAt", - "value": "2021-04-13T20:28:37.954Z", - "disabled": true - }, - { - "key": "status", - "value": "Scheduling", - "disabled": true - } ] } }, "response": [] }, { - "name": "Search interviews without token", + "name": "Search interviews with invalid token", "event": [ { "listen": "test", @@ -8111,7 +7665,7 @@ "pm.test('Status code is 401', function () {\r", " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"No token provided.\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -8120,7 +7674,13 @@ ], "request": { "method": "GET", - "header": [], + "header": [ + { + "key": "Authorization", + "value": "Bearer invalid_token", + "type": "text" + } + ], "url": { "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/interviews", "host": [ @@ -8136,7 +7696,7 @@ "response": [] }, { - "name": "Search interviews with invalid token", + "name": "Search interviews with invalid token Copy", "event": [ { "listen": "test", @@ -8174,6 +7734,170 @@ } }, "response": [] + }, + { + "name": "Get zoom-link without token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/getInterview/{{interviewId}}/zoom-link?type=host", + "host": [ + "{{URL}}" + ], + "path": [ + "getInterview", + "{{interviewId}}", + "zoom-link" + ], + "query": [ + { + "key": "type", + "value": "host" + } + ] + } + }, + "response": [] + }, + { + "name": "Get host zoom-link by guest token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/getInterview/{{interviewId}}/zoom-link?type=host&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiZ3Vlc3QiLCJpZCI6IjBkNWI1Y2MzLWQ1NjQtNDlhZC05ZGRmLWM5Zjc5MjRjYjY4NSIsImlhdCI6MTYzNzg5MDIzMSwiZXhwIjoxNjUzNDQyMjMxfQ.S54nYJ5FG4eF1OCFzQ44IGOdeyp30duZrA0APG1xOqg", + "host": [ + "{{URL}}" + ], + "path": [ + "getInterview", + "{{interviewId}}", + "zoom-link" + ], + "query": [ + { + "key": "type", + "value": "host" + }, + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiZ3Vlc3QiLCJpZCI6IjBkNWI1Y2MzLWQ1NjQtNDlhZC05ZGRmLWM5Zjc5MjRjYjY4NSIsImlhdCI6MTYzNzg5MDIzMSwiZXhwIjoxNjUzNDQyMjMxfQ.S54nYJ5FG4eF1OCFzQ44IGOdeyp30duZrA0APG1xOqg" + } + ] + } + }, + "response": [] + }, + { + "name": "Get guest zoom-link by host toke", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/getInterview/{{interviewId}}/zoom-link?type=guest&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiaG9zdCIsImlkIjoiMGQ1YjVjYzMtZDU2NC00OWFkLTlkZGYtYzlmNzkyNGNiNjg1IiwiaWF0IjoxNjM3ODkwMjMxLCJleHAiOjE2NTM0NDIyMzF9.cR6DCYvakmKrJGpbvSyvvhk_hs_jzhRZGGPwU-9cFY0", + "host": [ + "{{URL}}" + ], + "path": [ + "getInterview", + "{{interviewId}}", + "zoom-link" + ], + "query": [ + { + "key": "type", + "value": "guest" + }, + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiaG9zdCIsImlkIjoiMGQ1YjVjYzMtZDU2NC00OWFkLTlkZGYtYzlmNzkyNGNiNjg1IiwiaWF0IjoxNjM3ODkwMjMxLCJleHAiOjE2NTM0NDIyMzF9.cR6DCYvakmKrJGpbvSyvvhk_hs_jzhRZGGPwU-9cFY0" + } + ] + } + }, + "response": [] + }, + { + "name": "Get zoom-link by invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/getInterview/{{interviewId}}/zoom-link?type=host&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiaG9zdCIsImlkIjoiMGQ1YjVjYzMtZDU2NC00OWFkLTlkZGYtYzlmNzkyNGNiNjg1IiwiaWF0IjoxNjM3ODkwMjMxLCJleHAiOjE2NTM0NDIyMzF9.cR6DCYvakmKrJGpbvSyvvhk_hs_jzhRZGGPwU-9cFY0dae", + "host": [ + "{{URL}}" + ], + "path": [ + "getInterview", + "{{interviewId}}", + "zoom-link" + ], + "query": [ + { + "key": "type", + "value": "host" + }, + { + "key": "token", + "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiaG9zdCIsImlkIjoiMGQ1YjVjYzMtZDU2NC00OWFkLTlkZGYtYzlmNzkyNGNiNjg1IiwiaWF0IjoxNjM3ODkwMjMxLCJleHAiOjE2NTM0NDIyMzF9.cR6DCYvakmKrJGpbvSyvvhk_hs_jzhRZGGPwU-9cFY0dae" + } + ] + } + }, + "response": [] } ] }, @@ -20061,7 +19785,87 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + "value": "Bearer {{token_connect_manager_pshahcopmanag2}}" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/members-suggest/isbilir", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "members-suggest", + "isbilir" + ] + } + }, + "response": [] + }, + { + "name": "get member suggestion with member", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_member}}" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/members-suggest/isbilir", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "members-suggest", + "isbilir" + ] + } + }, + "response": [] + }, + { + "name": "get member suggestion with m2m", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403);\r", + " const response = pm.response.json()\r", + " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_m2m_all_job}}" } ], "url": { @@ -20079,16 +19883,16 @@ "response": [] }, { - "name": "get member suggestion with member", + "name": "get member suggestion with invalid token", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 401', function () {\r", + " pm.response.to.have.status(401);\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", + " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", "});" ], "type": "text/javascript" @@ -20101,7 +19905,7 @@ { "key": "Authorization", "type": "text", - "value": "Bearer {{token_member}}" + "value": "Bearer invalid" } ], "url": { @@ -20117,19 +19921,31 @@ } }, "response": [] - }, + } + ] + }, + { + "name": "User Meeting Settings", + "item": [ { - "name": "get member suggestion with m2m", + "name": "Get UserMeetingSettings", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 403', function () {\r", - " pm.response.to.have.status(403);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", + "});\r", + "\r", + "pm.test('nylasCalendars doesn\\'t contain accessToken or accountId', function () {\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"You are not allowed to perform this action!\")\r", - "});" + " _.each(response.nylasCalendars, (calendar) => {\r", + " pm.expect(calendar.accessToken).to.be.undefined\r", + " pm.expect(calendar.accountId).to.be.undefined\r", + " })\r", + "});\r", + "" ], "type": "text/javascript" } @@ -20140,36 +19956,43 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer {{token_m2m_all_job}}" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/taas-teams/members-suggest/isbilir", + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}", "host": [ "{{URL}}" ], "path": [ "taas-teams", - "members-suggest", - "isbilir" + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}" ] } }, "response": [] }, { - "name": "get member suggestion with invalid token", + "name": "Get UserMeetingSettings fromDb", "event": [ { "listen": "test", "script": { "exec": [ - "pm.test('Status code is 401', function () {\r", - " pm.response.to.have.status(401);\r", + "pm.test('Status code is 200', function () {\r", + " pm.response.to.have.status(200)\r", + "});\r", + "\r", + "pm.test('nylasCalendars doesn\\'t contain accessToken or accountId', function () {\r", " const response = pm.response.json()\r", - " pm.expect(response.message).to.eq(\"Invalid Token.\")\r", - "});" + " _.each(response.nylasCalendars, (calendar) => {\r", + " pm.expect(calendar.accessToken).to.be.undefined\r", + " pm.expect(calendar.accountId).to.be.undefined\r", + " })\r", + "});\r", + "" ], "type": "text/javascript" } @@ -20180,21 +20003,357 @@ "header": [ { "key": "Authorization", - "type": "text", - "value": "Bearer invalid" + "value": "Bearer {{token_bookingManager}}", + "type": "text" } ], "url": { - "raw": "{{URL}}/taas-teams/members-suggest/isbilir", + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}?fromDb=true", "host": [ "{{URL}}" ], "path": [ "taas-teams", - "members-suggest", - "isbilir" + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}" + ], + "query": [ + { + "key": "fromDb", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "Get UserMeetingSettings not found", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 404', function () {\r", + " pm.response.to.have.status(404)\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_bookingManager}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{$guid}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{$guid}}" + ] + } + }, + "response": [] + }, + { + "name": "Get UserMeetingSettings unauthorized", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 403', function () {\r", + " pm.response.to.have.status(403)\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_connectUser}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}" + ] + } + }, + "response": [] + }, + { + "name": "Delete Calendar from UserMeetingSettings record", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {", + " pm.response.to.have.status(204)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_of_usermeeting_settings_user}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}/calendars/{{idOfCalendarSavedInNylas}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}", + "calendars", + "{{idOfCalendarSavedInNylas}}" ] + }, + "description": "Endpoint for deleting a connected calendar from UserMeetingSettings record" + }, + "response": [] + }, + { + "name": "Delete Calendar from UserMeetingSettings record with m2m delete", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {", + " pm.response.to.have.status(204)", + "});", + "" + ], + "type": "text/javascript" + } } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_m2m_user_meeting_settings_calendar}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}/calendars/{{idOfCalendarSavedInNylas}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}", + "calendars", + "{{idOfCalendarSavedInNylas}}" + ] + }, + "description": "Endpoint for deleting a connected calendar from UserMeetingSettings record" + }, + "response": [] + }, + { + "name": "Delete Calendar from UserMeetingSettings record with \"hasManagePermissionUser\"", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 204', function () {", + " pm.response.to.have.status(204)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_has_manage_permission_user_meeting_settings_calendar}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}/calendars/{{idOfCalendarSavedInNylas}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}", + "calendars", + "{{idOfCalendarSavedInNylas}}" + ] + }, + "description": "Endpoint for deleting a connected calendar from UserMeetingSettings record" + }, + "response": [] + }, + { + "name": "Delete Calendar from UserMeetingSettings record with invalid token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 401', function () {", + " pm.response.to.have.status(401)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer invalid_token", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}/calendars/{{idOfCalendarSavedInNylas}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}", + "calendars", + "{{idOfCalendarSavedInNylas}}" + ] + }, + "description": "Endpoint for deleting a connected calendar from UserMeetingSettings record" + }, + "response": [] + }, + { + "name": "Delete Calendar from UserMeetingSettings record with invalid user id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {", + " pm.response.to.have.status(400)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_of_usermeeting_settings_user}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/invalid_userid/calendars/{{idOfCalendarSavedInNylas}}", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "invalid_userid", + "calendars", + "{{idOfCalendarSavedInNylas}}" + ] + }, + "description": "Endpoint for deleting a connected calendar from UserMeetingSettings record" + }, + "response": [] + }, + { + "name": "Delete Calendar from UserMeetingSettings record with invalid calendar id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('Status code is 400', function () {", + " pm.response.to.have.status(400)", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token_of_usermeeting_settings_user}}", + "type": "text" + } + ], + "url": { + "raw": "{{URL}}/taas-teams/user-meeting-settings/{{userIdWithUserMeetingSettings}}/calendars/invalid_calendar_id", + "host": [ + "{{URL}}" + ], + "path": [ + "taas-teams", + "user-meeting-settings", + "{{userIdWithUserMeetingSettings}}", + "calendars", + "invalid_calendar_id" + ] + }, + "description": "Endpoint for deleting a connected calendar from UserMeetingSettings record" }, "response": [] } @@ -34340,6 +34499,98 @@ }, "response": [] }, + { + "name": "Reschedule interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"Rescheduled\",\r\n \"startTimestamp\": \"2025-11-14T06:00:52.430Z\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" + ] + } + }, + "response": [] + }, + { + "name": "Cancelled interview", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [ + { + "key": "Authorization", + "type": "text", + "value": "Bearer {{token_bookingManager}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"status\": \"Cancelled\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{URL}}/jobCandidates/{{jobCandidateId}}/updateInterview/{{interviewRound}}", + "host": [ + "{{URL}}" + ], + "path": [ + "jobCandidates", + "{{jobCandidateId}}", + "updateInterview", + "{{interviewRound}}" + ] + } + }, + "response": [] + }, { "name": "[Interview Coming Up in 1 hour + Interview Completed]", "event": [ diff --git a/docs/guides/Setup-Interview-Workflow-Locally.md b/docs/guides/Setup-Interview-Workflow-Locally.md new file mode 100644 index 00000000..f53dd402 --- /dev/null +++ b/docs/guides/Setup-Interview-Workflow-Locally.md @@ -0,0 +1,82 @@ +# How to Setup Interview Workflow Locally + +Interview scheduling functionality uses a third-party service https://www.nylas.com/. To be able to test interview scheduling locally you would have to create a Nylas account and properly config it. + +## 1. Create a Nylas Account + +Go to https://www.nylas.com/ and register a free account. + +## 2. Create a new Nylas app + +1. Login to the Nylas Dashboard https://dashboard.nylas.com. +2. On the left sidebar choose **All Applications** ⟶ **Create New App**. +3. Fill **App Name** and select `Web` for **On which platform are you developing first?**. Click **Create Application** +4. After this your new app would be created. +5. Now, choose your application in the left sidebar **All Applications** ⟶ **{Your App Name}**. And then click **App Setting** in the left side bar. +6. Find on the page **Client ID** and **Client Secret**. Add them to the `.env` file inside `taas-apis` folder: + + ```sh + # .env + + NYLAS_CLIENT_ID={Client ID} + NYLAS_CLIENT_SECRET={Client Secret} + ``` + +## 3. Config Webhooks URL + +1. Make `http://localhost:3000` available for everyone using public domain. For example using https://ngrok.com/: + + ```sh + ngrok http 3000 + + # output + Forwarding https://XXXX-XXX-XXX-XXX-XXX.ngrok.io -> http://localhost:3000 + ``` +2. Add this public webhook base URL to the `.env` file inside `taas-apis` folder: + + ```sh + # .env + + NYLAS_SCHEDULER_WEBHOOK_BASE_URL=https://XXXX-XXX-XXX-XXX-XXX.ngrok.io/api/v5 + ``` + +3. Run TaaS API locally as per [the main local setup guide](../../README.md#steps-to-run-locally). + - If it was already run, then restart it to pick up `NYLAS_SCHEDULER_WEBHOOK_BASE_URL` env variable. + - Make sure, that TaaS API is run on port `3000`. +4. Login to the Nylas Dashboard https://dashboard.nylas.com again and choose your application in the left sidebar **All Applications** ⟶ **{Your App Name}**. +5. Now choose **Webhooks** in the left sidebar. And then click **Create Webhook** button. +6. Fill **Callback URL** as `https://XXXX-XXX-XXX-XXX-XXX.ngrok.io/api/v5/taas-teams/nylas-webhooks` (use domain name generated by ngrok) and select `event.created`, `event.updated` and `event.deleted` triggers. You may also just set **Select All** checkbox to select all triggers. +7. Now click **Create Webhook** button. + - ⚠️ During webhook creating it would check if Webhook URL works good. If you get error during creating webhook make sure that TaaS API is running and is accessible by the public URL. Open URL `https://XXXX-XXX-XXX-XXX-XXX.ngrok.io/api/v5/taas-teams/nylas-webhooks?challenge=test` with `?challenge=test` - it should return `test` in response. + +## 4. [Optional] Config Calendar Providers + +You don't have to make this step if you don't want to test connect Google or Microsoft calendars functionality. + +### 4.1. Config Nylas Auth Callback + +To be able to connect any calendar first we have to set the callback url. + +1. Login to the Nylas Dashboard https://dashboard.nylas.com again and choose your application in the left sidebar **All Applications** ⟶ **{Your App Name}**. +2. Choose **Authentication** tab on this page. +3. Fill **Add your callback** with `http://localhost:3000/api/v5/taas-teams/user-meeting-settings/callback` (don't need public domain here, `localhost` is fine). And click **Add Callback** blue link to add this callback URL. + - Make sure that now this callback URL is now shown under the empty input field. + +### 4.2. Config Google Auth + +To be able to connect Google calendars we have to create a Google Application and provide its credentials here. + +Follow this guide https://developer.nylas.com/docs/the-basics/provider-guides/google/create-google-app/#create-a-google-app on how to create a Google Application and config it inside Nylas. + +During this guide you would have a choice: + +- Choose `Hosted Authentication`. +- Choose `External Application`. + +### 4.2. Config Microsoft Auth + +To be able to connect Microsoft (Exchange) calendars we have to create an Azure (Microsoft) Application and provide its credentials here. + +Follow this guide https://developer.nylas.com/docs/the-basics/provider-guides/microsoft/create-azure-app/#new-app-registration on how to create a Google Application and config it inside Nylas. + +During this guide you would have to provide permissions. To do so you would have to update your Manifest JSON: find section `requiredResourceAccess` and add objects from this guide if these objects are not yet there. diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 3a1b3776..564f5460 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -15,6 +15,7 @@ tags: - name: Jobs - name: JobCandidates - name: Interviews + - name: UserMeetingSettings - name: ResourceBookings - name: Teams - name: WorkPeriods @@ -137,10 +138,10 @@ paths: type: integer description: The maximum Salary. - in: query - name: isApplicationPageActive + name: isApplicationPageActive required: false schema: - type: boolean + type: boolean description: Is application page active. - in: query name: projectIds @@ -1107,7 +1108,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/UpdateInterviewRequestBody" + $ref: "#/components/schemas/UpdateInterviewByRequestBody" responses: "200": description: OK @@ -1158,7 +1159,7 @@ paths: parameters: - in: path name: id - description: The interview or xai id. + description: The interview id. required: true schema: type: string @@ -1166,7 +1167,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/UpdateInterviewRequestBody" + $ref: "#/components/schemas/UpdateInterviewByRequestBody" responses: "200": description: OK @@ -1391,7 +1392,7 @@ paths: parameters: - in: path name: id - description: The interview or xai id. + description: The interview id. required: true schema: type: string @@ -1438,6 +1439,70 @@ paths: application/json: schema: $ref: "#/components/schemas/Error" + + /getInterview/{id}/zoom-link: + get: + tags: + - Interviews + description: | + Get a fresh Zoom Links from Zoom Meeting and redirect to Zoom Link. + + parameters: + - in: path + name: id + description: The interview id. + required: true + schema: + type: string + - in: query + name: type + description: the zoom link type (host or guest). + required: true + schema: + type: string + enum: + - host + - guest + - in: query + name: token + description: the request token. + required: true + schema: + type: string + responses: + "302": + description: Redirect to link of Zoom Meeting + headers: + Location: + description: Zoom Meeting Link. + schema: + type: string + format: uri + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /resourceBookings: post: tags: @@ -3108,6 +3173,121 @@ paths: schema: $ref: "#/components/schemas/Error" + /taas-teams/user-meeting-settings/{userId}: + get: + tags: + - UserMeetingSettings + description: | + Get the User's Meeting Settings. + + **Authorization** This endpoint could be called by: "hasManagePermission" users, M2M tokens with scopes "read:taas-userMeetingsSettings" or "all:taas-userMeetingsSettings". Also any user can call this endpoint to get setting for themselves + security: + - bearerAuth: [] + parameters: + - in: path + name: userId + description: The userId + required: true + schema: + type: string + format: uuid + + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/UserMeetingSettings" + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /taas-teams/user-meeting-settings/{userId}/calendars/{calendarId}: + delete: + tags: + - UserMeetingSettings + description: | + Delete a calendar from the User's Meeting Settings' nylasCalendars array. + + This endpoint deletes a connected calendar in Nylas by deleting it from the nylasCalendars array inside UserMeetingSettings object. + Note, this does not delete the calendar in Nylas backend server - intentionally, it only deletes from UserMeetingSettings array. + security: + - bearerAuth: [] + parameters: + - in: path + name: userId + description: The UUID of the User whose calendar should be deleted + required: true + schema: + type: string + format: uuid + - in: path + name: calendarId + description: The id of the calendar to delete. This id comes from Nylas backend server + required: true + schema: + type: string + responses: + "204": + description: OK + "400": + description: Bad request + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "401": + description: Not authenticated + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "404": + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /taas-teams/{id}/invites: get: tags: @@ -3583,7 +3763,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/Error" + $ref: "#/components/schemas/Error" /taas-teams/createPayment: post: tags: @@ -3691,6 +3871,12 @@ paths: - Teams description: | Returns suggested members for the given handle fragment + parameters: + - in: path + name: fragment + required: true + schema: + type: string security: - bearerAuth: [] responses: @@ -4571,7 +4757,6 @@ components: required: - id - jobCandidateId - - templateUrl - round - status - createdAt @@ -4581,36 +4766,10 @@ components: type: string format: uuid description: "The interview id." - xaiId: - type: string - description: "The x.ai id." jobCandidateId: type: string format: uuid description: "The job candidate id." - calendarEventId: - type: string - example: "dummyId" - description: "The calendar event id." - templateUrl: - type: string - example: "interview-30" - enum: ["interview-30", "interview-60"] - description: "The x.ai template name" - templateId: - type: string - format: uuid - description: "The x.ai template id" - templateType: - type: string - description: "The x.ai template type" - title: - type: string - description: "The x.ai template title" - locationDetails: - type: string - example: "Location TBD." - description: "The x.ai meeting location." round: type: integer example: 1 @@ -4619,24 +4778,6 @@ components: type: integer example: 30 description: "The interview duration (in minutes)." - hostEmail: - type: string - format: email - description: "The interview host email." - hostName: - type: string - description: "The interview host name." - guestEmails: - type: array - description: "Attendee list for this interview." - items: - type: string - format: email - guestNames: - type: array - description: "Names of guests." - items: - type: string startTimestamp: type: string format: date-time @@ -4645,6 +4786,27 @@ components: type: string format: date-time description: "Interview end time." + hostTimezone: + type: string + description: "Timezone of interview host." + guestTimezone: + type: string + description: "Timezone of interview candidate." + nylasPageId: + type: string + description: 'Associated Nylas page id.' + nylasPageSlug: + type: string + description: 'Associated Nylas page slug.' + nylasCalendarId: + type: string + description: 'Associated Nylas calendar id.' + nylasEventId: + type: string + description: 'Associated Nylas event id.' + nylasEventEditHash: + type: string + description: 'Associated Nylas event edit hash.' status: type: string enum: @@ -4657,10 +4819,6 @@ components: "Cancelled", ] description: "The interview status." - rescheduleUrl: - type: string - format: url - description: "x.ai reschedule url." createdAt: type: string format: date-time @@ -4677,28 +4835,55 @@ components: type: string format: uuid description: "The user who updated the interview last time.(Will get the user info from the token)" - RequestInterviewBody: + CandidateInterview: required: - - templateUrl - - hostEmail + - id + - jobCandidateId + - round + - status + - createdAt + - createdBy properties: - calendarEventId: + id: type: string - example: "dummyId" - description: "The calendar event id." - templateUrl: + format: uuid + description: "The interview id." + hostFirstName: type: string - enum: ["interview-30", "interview-60"] - example: "interview-30" - description: "The x.ai template name" - hostEmail: + example: "nkumar" + description: "The firstName of the interview host" + hostLastName: type: string - format: email - guestEmails: - type: array - items: - type: string - format: email + example: "nkumar" + description: "The lastName of the interview host" + hostHandle: + type: string + example: "nkumartest" + description: "The handle of the interview host" + hostUserId: + type: string + example: "00000000-0000-0000-0000-000000000000" + description: "The userId of the interview host" + jobCandidateId: + type: string + format: uuid + description: "The job candidate id." + round: + type: integer + example: 1 + description: "The interview round." + duration: + type: integer + example: 30 + description: "The interview duration (in minutes)." + startTimestamp: + type: string + format: date-time + description: "Interview start time." + endTimestamp: + type: string + format: date-time + description: "Interview end time." status: type: string enum: @@ -4710,54 +4895,100 @@ components: "Completed", "Cancelled", ] - default: "Scheduling" description: "The interview status." - UpdateInterviewRequestBody: - properties: - xaiId: + createdAt: type: string - description: "The x.ai meeting id" - calendarEventId: + format: date-time + description: "The interview created date." + createdBy: type: string - example: "dummyId" - description: "The google calendar id." - templateUrl: + format: uuid + description: "The user who created the interview.(Will get the user info from the token)" + updatedAt: type: string - enum: ["interview-30", "interview-60"] - example: "interview-30" - description: "The x.ai template name" - templateId: + format: date-time + description: "The interview last updated at." + updatedBy: type: string format: uuid - description: "The x.ai template id" - templateType: + description: "The user who updated the interview last time.(Will get the user info from the token)" + RequestInterviewBody: + required: + - duration + - hostTimezone + - availableTime + properties: + duration: + type: integer + example: 30 + description: "duration of the interview" + hostTimezone: type: string - description: "The x.ai template type" - title: + example: "Europe/London" + availableTime: + type: array + items: + type: object + required: + - days + - start + - end + properties: + days: + type: array + items: + type: string + enum: ["M", "T", "W", "R", "F", "S", "U"] + start: + type: string + example: "09:00" + pattern: "^[0-9]{1,2}:[0-9]{2}$" + end: + type: string + example: "10:00" + pattern: "^[0-9]{1,2}:[0-9]{2}$" + hostUserId: type: string - description: "The x.ai meeting title" - locationDetails: + format: uuid + + UpdateInterviewByRequestBody: + properties: + duration: + type: integer + example: 30 + description: "duration of the interview" + hostTimezone: type: string - example: "Location TBD." - description: "The x.ai location details" - hostName: + example: "Europe/London" + hostUserId: type: string - description: "The host name" - hostEmail: + description: "UUID of interview host user" + expireTimestamp: type: string - format: email - description: "The host email" - guestNames: - type: array - items: - type: string - description: "The guest names" - guestEmails: + format: date-time + description: "Interview expiry time stamp." + availableTime: type: array items: - type: string - format: email - description: "The guest emails" + type: object + required: + - days + - start + - end + properties: + days: + type: array + items: + type: string + enum: ["M", "T", "W", "R", "F", "S", "U"] + start: + type: string + example: "09:00" + pattern: "^[0-9]{1,2}:[0-9]{2}$" + end: + type: string + example: "10:00" + pattern: "^[0-9]{1,2}:[0-9]{2}$" startTimestamp: type: string format: date-time @@ -4768,20 +4999,11 @@ components: description: "Interview end time." status: type: string - enum: - [ - "Scheduling", - "Scheduled", - "Requested for reschedule", - "Rescheduled", - "Completed", - "Cancelled", - ] - description: "The interview status." - rescheduleUrl: + enum: ["Scheduling", "Scheduled", "Requested for reschedule", "Rescheduled", "Completed", "Cancelled", "Expired"] + deletedAt: type: string - format: url - description: "The x.ai reschedule url" + format: date-time + JobPatchRequestBody: properties: status: @@ -5814,7 +6036,7 @@ components: interviews: type: array items: - $ref: "#/components/schemas/Interview" + $ref: "#/components/schemas/CandidateInterview" status: type: string enum: @@ -6474,6 +6696,67 @@ components: "id": "0bcb0d86-09bb-410a-b2b1-fba90d1a7699", "updated": "2021-01-05T10:58:32.113Z", } + UserMeetingSettings: + type: object + properties: + userId: + type: string + format: uuid + defaultAvailableTime: + type: array + items: + type: object + required: + - days + - start + - end + properties: + days: + type: array + items: + type: string + enum: ["M", "T", "W", "R", "F", "S", "U"] + start: + type: string + example: "09:00" + pattern: "^[0-9]{1,2}:[0-9]{2}$" + end: + type: string + example: "10:00" + pattern: "^[0-9]{1,2}:[0-9]{2}$" + defaultTimezone: + type: string + example: "Europe/Rome" + nylasCalendars: + type: array + items: + type: object + properties: + id: + type: string + format: uuid + isPrimary: + type: boolean + accountProvider: + type: string + createdAt: + type: string + format: date-time + description: "The setting created date." + createdBy: + type: string + format: uuid + description: "The user Id who created the setting.(Will get the user info from the token)" + updatedAt: + type: string + format: date-time + description: "The setting last updated at." + updatedBy: + type: string + format: uuid + description: "The user Id who updated the setting last time.(Will get the user info from the token)" + + Error: required: - message diff --git a/docs/topcoder-bookings.postman_environment.json b/docs/topcoder-bookings.postman_environment.json index d71657b4..d58d21f5 100644 --- a/docs/topcoder-bookings.postman_environment.json +++ b/docs/topcoder-bookings.postman_environment.json @@ -1,5 +1,5 @@ { - "id": "4135008f-c812-4b34-8b6c-efd2e066f78e", + "id": "80d342a2-0c09-4e6c-b7ba-82345a2ffb56", "name": "topcoder-bookings", "values": [ { @@ -551,9 +551,34 @@ "key": "clientUserToken", "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5VSkZORGd4UlRVME5EWTBOVVkzTlRkR05qTXlRamxETmpOQk5UYzVRVUV3UlRFeU56TTJRUSJ9.eyJodHRwczovL3RvcGNvZGVyLWRldi5jb20vcm9sZXMiOlsiVG9wY29kZXIgVXNlciJdLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vdXNlcklkIjoiODU0Nzg5OSIsImh0dHBzOi8vdG9wY29kZXItZGV2LmNvbS9oYW5kbGUiOiJwc2hhaF9tYW5hZ2VyIiwiaHR0cHM6Ly90b3Bjb2Rlci1kZXYuY29tL3VzZXJfaWQiOiJhdXRoMHw0MDE1Mjg1NiIsImh0dHBzOi8vdG9wY29kZXItZGV2LmNvbS90Y3NzbyI6IjQwMTUyODU2fDgxMzRmNDhlYmUxMWE4NDhhMzc1OWU1ZWY5ZTkyZjIxNDY5MmUyMTEzMDQwYzgyYjVkOGY1ODFjNmRmY2NjODgiLCJodHRwczovL3RvcGNvZGVyLWRldi5jb20vYWN0aXZlIjp0cnVlLCJuaWNrbmFtZSI6InBzaGFoX21hbmFnZXIiLCJuYW1lIjoidmlrYXMuYWdhcndhbCtwc2hhaF9tYW5hZ2VyQHRvcGNvZGVyLmNvbSIsInBpY3R1cmUiOiJodHRwczovL3MuZ3JhdmF0YXIuY29tL2F2YXRhci85MmFmYjJmMGVkNTJmZGZhZTFmMzcxMDIxYWU2NTAxMz9zPTQ4MCZyPXBnJmQ9aHR0cHMlM0ElMkYlMkZjZG4uYXV0aDAuY29tJTJGYXZhdGFycyUyRnZpLnBuZyIsInVwZGF0ZWRfYXQiOiIyMDIwLTEwLTI0VDA4OjI4OjI0LjE4NFoiLCJlbWFpbCI6InZpa2FzLmFnYXJ3YWwrcHNoYWhfbWFuYWdlckB0b3Bjb2Rlci5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6Ly9hdXRoLnRvcGNvZGVyLWRldi5jb20vIiwic3ViIjoiYXV0aDB8NDAxNTI4NTYiLCJhdWQiOiJCWFdYVVduaWxWVVBkTjAxdDJTZTI5VHcyWllOR1p2SCIsImlhdCI6MTYwMzU0MzMzOCwiZXhwIjozMzE2MDQ1MjczOCwibm9uY2UiOiJSMUEyY3pZdVZUWm1ialpIUkc5MlZsOURTVUo2VWxsdlFYYzNSSGg1UzNaV2RXWkRjRE5YTUVaMVh3PT0ifQ.HbAisH30DLcbFNQeIifSzk1yhDmlGHNpPi9LSZbAowo", "enabled": true + }, + { + "key": "userIdWithUserMeetingSettings", + "value": "", + "enabled": true + }, + { + "key": "idOfCalendarSavedInNylas", + "value": "", + "enabled": true + }, + { + "key": "token_of_usermeeting_settings_user", + "value": "", + "enabled": true + }, + { + "key": "token_m2m_user_meeting_settings_calendar", + "value": "", + "enabled": true + }, + { + "key": "token_has_manage_permission_user_meeting_settings_calendar", + "value": "", + "enabled": true } ], "_postman_variable_scope": "environment", - "_postman_exported_at": "2021-08-17T09:21:17.381Z", - "_postman_exported_using": "Postman/8.6.2" + "_postman_exported_at": "2021-10-19T09:41:08.628Z", + "_postman_exported_using": "Postman/8.12.4" } \ No newline at end of file diff --git a/local/docker-compose.yml b/local/docker-compose.yml index e8db578a..471af264 100644 --- a/local/docker-compose.yml +++ b/local/docker-compose.yml @@ -37,7 +37,7 @@ services: - zookeeper elasticsearch: - image: elasticsearch:7.7.1 + image: elasticsearch:7.8.0 container_name: tc-taas-elasticsearch environment: - discovery.type=single-node diff --git a/migrations/2021-09-30-interview-nylas.js b/migrations/2021-09-30-interview-nylas.js new file mode 100644 index 00000000..bf4b729e --- /dev/null +++ b/migrations/2021-09-30-interview-nylas.js @@ -0,0 +1,141 @@ +const config = require('config') +const { Interviews } = require('../app-constants') + +/* + * Add show_in_hot_list, featured, hot_list_excerpt and job_tag to the Job model. +type: Sequelize.BOOLEAN, + defaultValue: false, + allowNull: false + */ + + +const { nylasAvailableTimeSchema, nylasCalendarsSchema } = require('../src/common/nylas') + + +module.exports = { + up: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction() + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const jobCandidatesTable = { tableName: 'job_candidates', schema: config.DB_SCHEMA_NAME } + try { + // log which Job Candidates in "interview" status would become "open" to be aware + const jcWithInterview = await queryInterface.sequelize.query(`SELECT id FROM bookings.job_candidates WHERE status = 'interview';`) + const jcIds = jcWithInterview[0].map(jc => jc.id) + console.log(`NOTE: Job Candidates in "interview" status which would become "open" again, total: ${jcIds.length}, ids: ${jcIds.join(', ')}`) + + // update all existent Job Candidates which are in the interview process to come back to `open` status + await queryInterface.bulkUpdate(jobCandidatesTable, + { + status: 'open' + }, + { + status: 'interview' + } + ); + + // remove all existent interview records as they are not compatible with new workflow + await queryInterface.bulkDelete(interviewsTable, {}, { transaction }) + + // remove not needed columns from interviews + await queryInterface.removeColumn(interviewsTable, 'xai_id', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'calendar_event_id', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'template_url', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'template_id', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'template_type', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'location_details', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'reschedule_url', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'title', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'host_name', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'host_email', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'guest_names', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'guest_emails', { transaction }) + + //add columns to interviews + await queryInterface.addColumn(interviewsTable, 'nylas_page_id', { type: Sequelize.STRING(255), allowNull: false}, { transaction }) + await queryInterface.addColumn(interviewsTable, 'nylas_page_slug', { type: Sequelize.STRING(255), allowNull: false}, { transaction }) + await queryInterface.addColumn(interviewsTable, 'nylas_calendar_id', { type: Sequelize.STRING(255), allowNull: false}, { transaction }) + await queryInterface.addColumn(interviewsTable, 'timezone', { type: Sequelize.STRING(255), allowNull: false}, { transaction }) + await queryInterface.addColumn(interviewsTable, 'availableTime', nylasAvailableTimeSchema('availableTime'), { transaction }) + await queryInterface.addColumn(interviewsTable, 'hostUserId', { type: Sequelize.UUID, allowNull: false}, { transaction }) + await queryInterface.addColumn(interviewsTable, 'expireTimestamp', { type: Sequelize.DATE, allowNull: true}, { transaction }) + //new UserMeetingSettings + await queryInterface.createTable('user_meeting_settings', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4 + }, + defaultAvailableTime: nylasAvailableTimeSchema('defaultAvailableTime'), + defaultTimezone: { + field: 'defaultTimezone', + type: Sequelize.STRING(255) + }, + nylasCalendars: nylasCalendarsSchema(), + createdBy: { + field: 'created_by', + type: Sequelize.UUID, + allowNull: false + }, + updatedBy: { + field: 'updated_by', + type: Sequelize.UUID + }, + createdAt: { + field: 'created_at', + type: Sequelize.DATE + }, + updatedAt: { + field: 'updated_at', + type: Sequelize.DATE + }, + deletedAt: { + field: 'deleted_at', + type: Sequelize.DATE + } + }, { schema: config.DB_SCHEMA_NAME, transaction }) + + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + }, + down: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction() + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + try { + + await queryInterface.dropTable('user_meeting_settings', { transaction }) + + await queryInterface.removeColumn(interviewsTable, 'nylas_page_id', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'nylas_page_slug', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'nylas_calendar_id', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'timezone', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'availableTime', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'hostUserId', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'expireTimestamp', { transaction }) + + await queryInterface.addColumn(interviewsTable, 'xai_id', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'calendar_event_id', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'template_url', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'template_id', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'template_type', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'location_details', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'reschedule_url', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'title', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'host_name', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'host_email', { type: Sequelize.STRING(255) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'guest_names', { type: Sequelize.ARRAY(Sequelize.STRING) }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'guest_emails', { type: Sequelize.ARRAY(Sequelize.STRING) }, { transaction }) + + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +} diff --git a/migrations/2021-10-13-change-interview-status.js b/migrations/2021-10-13-change-interview-status.js new file mode 100644 index 00000000..34131b3c --- /dev/null +++ b/migrations/2021-10-13-change-interview-status.js @@ -0,0 +1,49 @@ +"use strict"; +const config = require("config"); + +/** + * Add Expired for status enum field + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction(); + // const table = { tableName: "interviews", schema: config.DB_SCHEMA_NAME }; + try { + await queryInterface.sequelize.query( + `ALTER TYPE ${config.DB_SCHEMA_NAME}.enum_interviews_status ADD VALUE 'Expired'` + ); + await transaction.commit(); + } catch (err) { + await transaction.rollback(); + throw err; + } + }, + + down: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction(); + + try { + queryInterface.sequelize.query( + ` + DELETE + FROM + pg_enum + WHERE + enumlabel = 'Expired' AND + enumtypid = ( + SELECT + oid + FROM + pg_type + WHERE + typname = 'enum_interviews_status' + ) + ` + ); + await transaction.commit(); + } catch (err) { + await transaction.rollback(); + throw err; + } + }, +}; diff --git a/migrations/2021-11-07-add-nylas-event-fields-in-interview.js b/migrations/2021-11-07-add-nylas-event-fields-in-interview.js new file mode 100644 index 00000000..af59eddf --- /dev/null +++ b/migrations/2021-11-07-add-nylas-event-fields-in-interview.js @@ -0,0 +1,57 @@ +'use strict'; +const config = require('config') + +module.exports = { + up: async (queryInterface, Sequelize) => { + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const jobCandidatesTable = { tableName: 'job_candidates', schema: config.DB_SCHEMA_NAME } + const transaction = await queryInterface.sequelize.transaction() + + try { + // log which Job Candidates in "interview" status would become "open" to be aware + const jobCandidatesWithInterview = await queryInterface.sequelize.query(`SELECT id FROM bookings.job_candidates WHERE status = 'interview';`) + const jobCandidateIds = jobCandidatesWithInterview[0].map(jc => jc.id) + console.log(`NOTE: Job Candidates in "interview" status which would become "open" for interview again, total: ${jobCandidateIds.length}, ids: ${jobCandidateIds.join(', ')}`) + + // update all existent Job Candidates which are in the interview process to come back to `open` status + await queryInterface.bulkUpdate(jobCandidatesTable, + { + status: 'open' + }, + { + status: 'interview' + } + ); + + // remove all existent interview records as they are not compatible with new workflow + await queryInterface.bulkDelete(interviewsTable, {}, { transaction }) + + // add new columns nylas_event_id & nylas_event_edit_hash + await queryInterface.addColumn(interviewsTable, 'nylas_event_id', + { type: Sequelize.STRING(255), allowNull: true, defaultValue: null }, + { transaction }) + await queryInterface.addColumn(interviewsTable, 'nylas_event_edit_hash', + { type: Sequelize.STRING(255), allowNull: true, defaultValue: null }, + { transaction }) + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + }, + down: async (queryInterface, Sequelize) => { + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const transaction = await queryInterface.sequelize.transaction() + + try { + await queryInterface.removeColumn(interviewsTable, 'nylas_event_id', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'nylas_event_edit_hash', { transaction }) + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +}; diff --git a/migrations/2021-11-09-update-interview-timezone-fields.js b/migrations/2021-11-09-update-interview-timezone-fields.js new file mode 100644 index 00000000..e5c23a36 --- /dev/null +++ b/migrations/2021-11-09-update-interview-timezone-fields.js @@ -0,0 +1,38 @@ +'use strict'; +const config = require('config') + +module.exports = { + up: async (queryInterface, Sequelize) => { + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const transaction = await queryInterface.sequelize.transaction() + + try { + // renamed column timezone to host_timezone & added new column & guest_timezone + // also populated the guest_timezone column with host_timezone column values + await queryInterface.renameColumn(interviewsTable, 'timezone', 'host_timezone', { transaction }) + await queryInterface.addColumn(interviewsTable, 'guest_timezone', { type: Sequelize.STRING(255) }, { transaction }) + + await queryInterface.sequelize.query(`UPDATE ${config.DB_SCHEMA_NAME}.interviews SET guest_timezone = host_timezone`, + { transaction }) + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + }, + down: async (queryInterface, Sequelize) => { + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const transaction = await queryInterface.sequelize.transaction() + + try { + await queryInterface.rename(interviewsTable, 'host_timezone', 'timezone', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'guest_timezone', { transaction }) + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +}; diff --git a/migrations/2021-11-25-add-interview-zoom-fields.js b/migrations/2021-11-25-add-interview-zoom-fields.js new file mode 100644 index 00000000..12d9f93f --- /dev/null +++ b/migrations/2021-11-25-add-interview-zoom-fields.js @@ -0,0 +1,51 @@ +'use strict'; +const config = require('config') + +/* + * Add zoomAccountApiKey, zoomMeetingId to the Interview model. + */ +module.exports = { + up: async (queryInterface, Sequelize) => { + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const jobCandidatesTable = { tableName: 'job_candidates', schema: config.DB_SCHEMA_NAME } + const transaction = await queryInterface.sequelize.transaction() + try { + // log which Job Candidates in "interview" status would become "open" to be aware + const jobCandidatesWithInterview = await queryInterface.sequelize.query(`SELECT id FROM bookings.job_candidates WHERE status = 'interview';`) + const jobCandidateIds = jobCandidatesWithInterview[0].map(jc => jc.id) + console.log(`NOTE: Job Candidates in "interview" status which would become "open" for interview again, total: ${jobCandidateIds.length}, ids: ${jobCandidateIds.join(', ')}`) + + // update all existent Job Candidates which are in the interview process to come back to `open` status + await queryInterface.bulkUpdate(jobCandidatesTable, + { + status: 'open' + }, + { + status: 'interview' + } + ); + + // remove all existent interview records as they are not compatible with new workflow + await queryInterface.bulkDelete(interviewsTable, {}, { transaction }) + + await queryInterface.addColumn(interviewsTable, 'zoom_account_api_key', { type: Sequelize.STRING(255), allowNull: true }, { transaction }) + await queryInterface.addColumn(interviewsTable, 'zoom_meeting_id', { type: Sequelize.BIGINT, allowNull: true }, { transaction }) + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + }, + down: async (queryInterface, Sequelize) => { + const interviewsTable = { tableName: 'interviews', schema: config.DB_SCHEMA_NAME } + const transaction = await queryInterface.sequelize.transaction() + try { + await queryInterface.removeColumn(interviewsTable, 'zoom_account_api_key', { transaction }) + await queryInterface.removeColumn(interviewsTable, 'zoom_meeting_id', { transaction }) + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +}; diff --git a/migrations/2021-12-01-add-uuid-for-nylas-calendars.js b/migrations/2021-12-01-add-uuid-for-nylas-calendars.js new file mode 100644 index 00000000..8df6f4ce --- /dev/null +++ b/migrations/2021-12-01-add-uuid-for-nylas-calendars.js @@ -0,0 +1,61 @@ +'use strict'; +const config = require('config') +const { v4: uuid } = require('uuid') +const _ = require('lodash') + +module.exports = { + up: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction() + + try { + const userMeetingsSettingsIdsResponse = await queryInterface.sequelize.query(`SELECT id, "nylasCalendars" FROM ${config.DB_SCHEMA_NAME}.user_meeting_settings;`) + const userMeetingsSettings = userMeetingsSettingsIdsResponse[0] + + // copy `id` to `calendarId` + // add `id` as UUID + userMeetingsSettings.forEach(({ nylasCalendars }) => { + nylasCalendars.forEach((calendar) => { + calendar.calendarId = calendar.id + calendar.id = uuid() + }) + }) + + for (let { id, nylasCalendars } of userMeetingsSettings) { + await queryInterface.sequelize.query(`UPDATE ${config.DB_SCHEMA_NAME}.user_meeting_settings SET "nylasCalendars" = '${JSON.stringify(nylasCalendars)}'::jsonb WHERE id = '${id}'`, + { transaction }) + } + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + }, + down: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction() + + try { + const userMeetingsSettingsIdsResponse = await queryInterface.sequelize.query(`SELECT id, "nylasCalendars" FROM ${config.DB_SCHEMA_NAME}.user_meeting_settings;`) + const userMeetingsSettings = userMeetingsSettingsIdsResponse[0] + + // copy `calendarId` to `id` + // delete `calendarId` + userMeetingsSettings.forEach(({ nylasCalendars }) => { + nylasCalendars.forEach((calendar) => { + calendar.id = calendar.calendarId + delete calendar.calendarId + }) + }) + + for (let { id, nylasCalendars } of userMeetingsSettings) { + await queryInterface.sequelize.query(`UPDATE ${config.DB_SCHEMA_NAME}.user_meeting_settings SET "nylasCalendars" = '${JSON.stringify(nylasCalendars)}'::jsonb WHERE id = '${id}'`, + { transaction }) + } + + await transaction.commit() + } catch (err) { + await transaction.rollback() + throw err + } + } +}; diff --git a/package-lock.json b/package-lock.json index 0e9b8be3..4e7c0f1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,10 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@elastic/elasticsearch": "^7.9.1", + "@elastic/elasticsearch": "7.9.1", "@joi/date": "^2.0.1", "@topcoder-platform/topcoder-bus-api-wrapper": "github:topcoder-platform/tc-bus-api-wrapper", + "async-mutex": "^0.3.2", "aws-sdk": "^2.787.0", "bottleneck": "^2.19.5", "config": "^3.3.2", @@ -23,6 +24,7 @@ "http-status": "^1.4.2", "http-status-codes": "^2.1.4", "joi": "^17.2.1", + "jsonwebtoken": "^8.5.1", "lodash": "^4.17.20", "moment": "^2.29.1", "moment-timezone": "^0.5.33", @@ -30,11 +32,13 @@ "pg": "^8.4.0", "pg-hstore": "^2.3.3", "prompt-confirm": "^2.0.4", + "retry": "^0.13.1", "rewire": "^5.0.0", "sequelize": "^6.3.5", "stripe": "^8.168.0", "superagent": "^6.1.0", "tc-core-library-js": "github:appirio-tech/tc-core-library-js#v2.6", + "urijs": "^1.19.7", "util": "^0.12.3", "uuid": "^8.3.1", "winston": "^3.3.3" @@ -53,34 +57,45 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dependencies": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", - "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.6", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.5", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.5", - "@babel/types": "^7.11.5", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "engines": { @@ -91,173 +106,254 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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)", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/core/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/@babel/core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=0.10.0" } }, "node_modules/@babel/generator": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", - "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, "dependencies": { - "@babel/types": "^7.11.5", + "@babel/types": "^7.15.6", "jsesc": "^2.5.1", "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "dependencies": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "dependencies": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "dependencies": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "dependencies": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "dependencies": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "dependencies": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "dependencies": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -267,49 +363,37 @@ } }, "node_modules/@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", - "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.5", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.5", - "@babel/types": "^7.11.5", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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)", - "dev": true, - "dependencies": { - "ms": "2.1.2" + "globals": "^11.1.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/globals": { @@ -321,21 +405,17 @@ "node": ">=4" } }, - "node_modules/@babel/traverse/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/@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@dabh/diagnostics": { @@ -363,23 +443,6 @@ "node": ">=8" } }, - "node_modules/@elastic/elasticsearch/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@elastic/elasticsearch/node_modules/decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -402,41 +465,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@elastic/elasticsearch/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/@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "deprecated": "Moved to 'npm install @sideway/address'", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==", - "deprecated": "Moved to 'npm install @sideway/formula'" - }, "node_modules/@hapi/hoek": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.0.tgz", - "integrity": "sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw==" - }, - "node_modules/@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==", - "deprecated": "Moved to 'npm install @sideway/pinpoint'" + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", + "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==" }, "node_modules/@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -457,6 +494,15 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -509,24 +555,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/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/@istanbuljs/load-nyc-config/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -537,22 +565,40 @@ } }, "node_modules/@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/@joi/date": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@joi/date/-/date-2.0.1.tgz", - "integrity": "sha512-vAnBxaPmyXRmHlbr5H3zY6x8ToW1a3c3gCo91dsf/HPKP2vS4sz2xzjyCE1up0vmFmSWgfDIyJMpRWVOG2cpZQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@joi/date/-/date-2.1.0.tgz", + "integrity": "sha512-2zN5m0LgxZp/cynHGbzEImVmFIa+n+IOb/Nlw5LX/PLJneeCwG1NbiGw7MvPjsAKUGQK8z31Nn6V6lEN+4fZhg==", "dependencies": { "moment": "2.x.x" } }, + "node_modules/@sideway/address": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", + "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -563,9 +609,9 @@ } }, "node_modules/@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" @@ -580,20 +626,10 @@ "@sinonjs/commons": "^1.7.0" } }, - "node_modules/@sinonjs/formatio": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", - "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^5.0.2" - } - }, "node_modules/@sinonjs/samsam": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz", - "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.6.0", @@ -647,19 +683,6 @@ "ms": "^2.1.1" } }, - "node_modules/@topcoder-platform/topcoder-bus-api-wrapper/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/@topcoder-platform/topcoder-bus-api-wrapper/node_modules/joi": { "version": "13.7.0", "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", @@ -674,33 +697,6 @@ "node": ">=8.9.0" } }, - "node_modules/@topcoder-platform/topcoder-bus-api-wrapper/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/@topcoder-platform/topcoder-bus-api-wrapper/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/@topcoder-platform/topcoder-bus-api-wrapper/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/@topcoder-platform/topcoder-bus-api-wrapper/node_modules/superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -747,31 +743,26 @@ "dev": true }, "node_modules/@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==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, "node_modules/@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==", + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/express": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", - "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -789,9 +780,9 @@ } }, "node_modules/@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==", + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", + "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -799,17 +790,17 @@ } }, "node_modules/@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==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz", + "integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==", "dependencies": { "@types/express": "*" } }, "node_modules/@types/lodash": { - "version": "4.14.172", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", - "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==", + "version": "4.14.175", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz", + "integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==", "dev": true }, "node_modules/@types/mime": { @@ -818,29 +809,35 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "14.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", - "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==" + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", + "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" }, "node_modules/@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "node_modules/@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==" + "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/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==", + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -860,9 +857,9 @@ } }, "node_modules/acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "bin": { "acorn": "bin/acorn" }, @@ -871,9 +868,9 @@ } }, "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -889,27 +886,6 @@ "node": ">= 6.0.0" } }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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==" - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -924,9 +900,9 @@ } }, "node_modules/ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "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", @@ -939,41 +915,56 @@ } }, "node_modules/ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, "dependencies": { - "string-width": "^3.0.0" + "string-width": "^4.1.0" } }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "node_modules/ansi-align/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" + } }, "node_modules/ansi-align/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/ansi-align/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" + } + }, + "node_modules/ansi-align/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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/ansi-bgblack": { @@ -1098,12 +1089,40 @@ } }, "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz", + "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=", + "dependencies": { + "ansi-bgblack": "^0.1.1", + "ansi-bgblue": "^0.1.1", + "ansi-bgcyan": "^0.1.1", + "ansi-bggreen": "^0.1.1", + "ansi-bgmagenta": "^0.1.1", + "ansi-bgred": "^0.1.1", + "ansi-bgwhite": "^0.1.1", + "ansi-bgyellow": "^0.1.1", + "ansi-black": "^0.1.1", + "ansi-blue": "^0.1.1", + "ansi-bold": "^0.1.1", + "ansi-cyan": "^0.1.1", + "ansi-dim": "^0.1.1", + "ansi-gray": "^0.1.1", + "ansi-green": "^0.1.1", + "ansi-grey": "^0.1.1", + "ansi-hidden": "^0.1.1", + "ansi-inverse": "^0.1.1", + "ansi-italic": "^0.1.1", + "ansi-magenta": "^0.1.1", + "ansi-red": "^0.1.1", + "ansi-reset": "^0.1.1", + "ansi-strikethrough": "^0.1.1", + "ansi-underline": "^0.1.1", + "ansi-white": "^0.1.1", + "ansi-yellow": "^0.1.1", + "lazy-cache": "^2.0.1" + }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, "node_modules/ansi-cyan": { @@ -1129,11 +1148,11 @@ } }, "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dependencies": { - "type-fest": "^0.11.0" + "type-fest": "^0.21.3" }, "engines": { "node": ">=8" @@ -1143,11 +1162,11 @@ } }, "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1242,11 +1261,11 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/ansi-reset": { @@ -1329,9 +1348,9 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -1397,43 +1416,22 @@ "node": ">=0.10.0" } }, - "node_modules/array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "node_modules/array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "dependencies": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -1476,9 +1474,22 @@ } }, "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" + }, + "node_modules/async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/async-mutex/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, "node_modules/asynckit": { "version": "0.4.0", @@ -1486,33 +1497,41 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/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==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.17.0.tgz", + "integrity": "sha512-rqHhOq6ZgOaHwz0e46YywsGW4Y2wLF3Fu+y2wT94vbEFNAi5vyJHJYVyNAetAN7w7Ljhda/7SsUs/usuEMRBpQ==", "dependencies": { - "base64-js": "^1.3.0", - "idtoken-verifier": "^2.0.3", + "base64-js": "^1.5.1", + "idtoken-verifier": "^2.2.2", "js-cookie": "^2.2.0", - "qs": "^6.7.0", + "qs": "^6.10.1", "superagent": "^5.3.1", "url-join": "^4.0.1", "winchan": "^0.2.2" } }, - "node_modules/auth0-js/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/auth0-js/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dependencies": { - "ms": "2.1.2" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=6.0" + "node": ">= 6" + } + }, + "node_modules/auth0-js/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==", + "dependencies": { + "yallist": "^4.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "engines": { + "node": ">=10" } }, "node_modules/auth0-js/node_modules/mime": { @@ -1526,10 +1545,32 @@ "node": ">=4.0.0" } }, - "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/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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/auth0-js/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, "node_modules/auth0-js/node_modules/superagent": { "version": "5.3.1", @@ -1552,27 +1593,15 @@ "node": ">= 7.0.0" } }, - "node_modules/auth0-js/node_modules/superagent/node_modules/qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/auth0-js/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/available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "dependencies": { - "array-filter": "^1.0.0" - }, + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "engines": { "node": ">= 0.4" }, @@ -1581,9 +1610,10 @@ } }, "node_modules/aws-sdk": { - "version": "2.787.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.787.0.tgz", - "integrity": "sha512-3WlUdWqUB8Vhdvj/7TENr/7SEmQzxmnHxOJ8l2WjZbcMRSuI0/9Ym4p1TC3hf21VDVDhkdGlw60QqpZQ1qb+Mg==", + "version": "2.1011.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1011.0.tgz", + "integrity": "sha512-U5CDmLUHYAur89+Rx1r3X5gRzc8ib90G9aaKnyGqLsIail24r6UINejJB8pyOzFQ+u22/kFKKclfXcTj/Hflbg==", + "hasInstallScript": true, "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -1650,14 +1680,28 @@ } }, "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "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==" + "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" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -1679,9 +1723,9 @@ } }, "node_modules/binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, "engines": { "node": ">=8" @@ -1713,40 +1757,69 @@ "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": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "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" + } + }, "node_modules/bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "node_modules/boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", "dev": true, "dependencies": { "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/boxen/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" + } + }, "node_modules/boxen/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { @@ -1757,16 +1830,19 @@ } }, "node_modules/boxen/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/boxen/node_modules/color-convert": { @@ -1796,6 +1872,41 @@ "node": ">=8" } }, + "node_modules/boxen/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/boxen/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1808,6 +1919,18 @@ "node": ">=8" } }, + "node_modules/boxen/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" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1835,6 +1958,29 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/browserslist": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", + "escalade": "^3.1.1", + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, "node_modules/buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -1970,12 +2116,25 @@ } }, "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001270", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001270.tgz", + "integrity": "sha512-TcIC7AyNWXhcOmv2KftOl1ShFAaHQYcB/EPL/hEyMrcS7ZX0/DvV1aoy6BzV0+16wTpoAyTMGDNAJfSqS/rz7A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, "node_modules/caseless": { @@ -1984,16 +2143,16 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "node_modules/chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "dev": true, "dependencies": { "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", + "pathval": "^1.1.1", "type-detect": "^4.0.5" }, "engines": { @@ -2040,10 +2199,23 @@ "node": ">=0.10.0" } }, + "node_modules/choices-separator/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/choices-separator/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "dependencies": { "anymatch": "~3.1.1", @@ -2052,13 +2224,13 @@ "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.1" } }, "node_modules/ci-info": { @@ -2131,43 +2303,58 @@ } }, "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "node_modules/cliui/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" + } }, "node_modules/cliui/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" + } + }, + "node_modules/cliui/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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/clone-deep": { @@ -2252,9 +2439,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "node_modules/color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -2311,26 +2498,32 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "node_modules/config": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/config/-/config-3.3.2.tgz", - "integrity": "sha512-NlGfBn2565YA44Irn7GV5KHlIGC3KJbf0062/zW5ddP9VXIuRj0m7HVyFAWvMZvaHPEglyGfwmevGz3KosIpCg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/config/-/config-3.3.6.tgz", + "integrity": "sha512-Hj5916C5HFawjYJat1epbyY2PlAgLpBtDUlr0MxGLgo3p5+7kylyvnRY18PqJHgnNWXcdd0eWDemT7eYWuFgwg==", "dependencies": { "json5": "^2.1.1" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 10.0.0" } }, "node_modules/config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -2383,9 +2576,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "dependencies": { "safe-buffer": "~5.1.1" @@ -2405,9 +2598,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "node_modules/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" }, "node_modules/copy-descriptor": { "version": "0.1.1", @@ -2425,9 +2618,9 @@ "hasInstallScript": true }, "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=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -2442,12 +2635,12 @@ } }, "node_modules/cron-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.3.0.tgz", - "integrity": "sha512-Tz5WxSrDVhR7YVuLuUxhXoMGHCWoe8I7g8APkyRZNaINXHQ3zcfK97av6hBYy9ue4sOLI7ZH7SeQqi/t4jR+5A==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.5.0.tgz", + "integrity": "sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==", "dependencies": { - "is-nan": "^1.3.0", - "luxon": "^1.25.0" + "is-nan": "^1.3.2", + "luxon": "^1.26.0" }, "engines": { "node": ">=0.8" @@ -2468,18 +2661,10 @@ "node": ">=4.8" } }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/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==" + "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/crypto-random-string": { "version": "2.0.0", @@ -2527,9 +2712,9 @@ } }, "node_modules/date-fns": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", - "integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==", + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz", + "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==", "engines": { "node": ">=0.11" }, @@ -2539,11 +2724,19 @@ } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dependencies": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/debug-log": { @@ -2555,13 +2748,21 @@ "node": ">=0.10.0" } }, + "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/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decompress-response": { @@ -2598,9 +2799,9 @@ } }, "node_modules/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=" + "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==" }, "node_modules/default-require-extensions": { "version": "3.0.0", @@ -2614,15 +2815,6 @@ "node": ">=8" } }, - "node_modules/default-require-extensions/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -2665,6 +2857,26 @@ "uniq": "^1.0.1" } }, + "node_modules/deglob/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/deglob/node_modules/ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", @@ -2696,9 +2908,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, "engines": { "node": ">=0.3.1" @@ -2728,11 +2940,11 @@ } }, "node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/dottie": { @@ -2801,20 +3013,17 @@ "yallist": "^2.1.2" } }, - "node_modules/editorconfig/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "node_modules/electron-to-chromium": { + "version": "1.3.873", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.873.tgz", + "integrity": "sha512-TiHlCgl2uP26Z0c67u442c0a2MZCWZNCRnPTQDPhVJ4h9G6z2zU0lApD9H0K9R5yFL5SfdaiVsVD2izOY24xBQ==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2850,6 +3059,12 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/error-ex/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 + }, "node_modules/error-symbol": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz", @@ -2859,21 +3074,30 @@ } }, "node_modules/es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dependencies": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2882,36 +3106,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "node_modules/es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "dev": true, - "dependencies": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -2983,6 +3177,15 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", @@ -3082,36 +3285,134 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" } }, "node_modules/eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", "dev": true, "dependencies": { - "debug": "^2.6.9", + "debug": "^3.2.7", + "find-up": "^2.1.0", "pkg-dir": "^2.0.0" }, "engines": { "node": ">=4" } }, - "node_modules/eslint-plugin-es": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz", - "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "eslint-utils": "^1.4.2", - "regexpp": "^3.0.0" + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils/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": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/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, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/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, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/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" + } + }, + "node_modules/eslint-module-utils/node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-es": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz", + "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^1.4.2", + "regexpp": "^3.0.0" }, "engines": { "node": ">=8.10.0" @@ -3121,9 +3422,9 @@ } }, "node_modules/eslint-plugin-es/node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, "engines": { "node": ">=8" @@ -3157,6 +3458,15 @@ "eslint": "2.x - 6.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": { + "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", @@ -3170,6 +3480,12 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, "node_modules/eslint-plugin-node": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz", @@ -3253,10 +3569,24 @@ } }, "node_modules/eslint-plugin-standard": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", - "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", + "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==", "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" + } + ], "peerDependencies": { "eslint": ">=5.0.0" } @@ -3292,28 +3622,14 @@ "node": ">=4" } }, - "node_modules/eslint/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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": { - "ms": "2.1.2" - }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=6" } }, - "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==" - }, "node_modules/eslint/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3322,6 +3638,17 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/espree": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", @@ -3348,9 +3675,9 @@ } }, "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dependencies": { "estraverse": "^5.1.0" }, @@ -3475,19 +3802,53 @@ "debug": "^2.2.0" } }, + "node_modules/express-interceptor/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express-interceptor/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "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": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "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/ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", "dev": true, "dependencies": { - "type": "^2.0.0" + "type": "^2.5.0" } }, "node_modules/ext/node_modules/type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", "dev": true }, "node_modules/extend": { @@ -3543,14 +3904,14 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "node_modules/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==" + "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/fecha": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", - "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" }, "node_modules/figures": { "version": "3.2.0", @@ -3606,10 +3967,23 @@ "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": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "dependencies": { "commondir": "^1.0.1", @@ -3623,130 +3997,78 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "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": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dependencies": { - "p-locate": "^4.1.0" + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dependencies": { - "p-try": "^2.0.0" + "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": ">=6" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/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/find-cache-dir/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "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": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "deprecated": "Fixed a prototype pollution security issue in 4.1.0, please upgrade to ^4.1.1 or ^5.0.1.", - "dev": true, - "dependencies": { - "is-buffer": "~2.0.3" + "glob": "^7.1.3" }, "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" + "rimraf": "bin.js" } }, "node_modules/flatted": { @@ -3778,6 +4100,11 @@ "ms": "2.0.0" } }, + "node_modules/follow-redirects/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -3883,30 +4210,31 @@ } }, "node_modules/form-data": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", - "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "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.8", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 6" + "node": ">= 0.12" } }, "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==", + "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" } }, "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "engines": { "node": ">= 0.6" } @@ -3920,9 +4248,9 @@ } }, "node_modules/fromentries": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.1.tgz", - "integrity": "sha512-Xu2Qh8yqYuDhQGOhD5iJGninErSfI9A3FrriD3tjUgV5VbJFeH8vfgZ9HnC6jWN80QDVNQK5vmxRAmEAp7Mevw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true, "funding": [ { @@ -3959,10 +4287,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, "optional": true, @@ -3984,9 +4311,9 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "node_modules/gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -4061,6 +4388,21 @@ "node": ">=6" } }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -4070,28 +4412,25 @@ } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, "dependencies": { - "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, @@ -4100,15 +4439,18 @@ } }, "node_modules/global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", "dev": true, "dependencies": { - "ini": "^1.3.5" + "ini": "2.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globals": { @@ -4148,9 +4490,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "node_modules/growl": { @@ -4183,15 +4525,6 @@ "uglify-js": "^3.1.4" } }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -4224,6 +4557,14 @@ "node": ">= 0.4.0" } }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -4233,9 +4574,23 @@ } }, "node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, "engines": { "node": ">= 0.4" }, @@ -4253,9 +4608,9 @@ } }, "node_modules/hasha": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.1.tgz", - "integrity": "sha512-x15jnRSHTi3VmH+oHtVb9kgU/HuKOK8mjK8iCL3dPQXh4YJlUb9YSI8ZLiiqLAIvY2wuDIlZYZppy8vB2XISkQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, "dependencies": { "is-stream": "^2.0.0", @@ -4297,9 +4652,9 @@ } }, "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/html-escaper": { @@ -4329,6 +4684,11 @@ "node": ">= 0.6" } }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, "node_modules/http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -4342,27 +4702,6 @@ "node": ">= 6" } }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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", @@ -4378,9 +4717,9 @@ } }, "node_modules/http-status": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.4.2.tgz", - "integrity": "sha512-mBnIohUwRw9NyXMEMMv8/GANnzEYUj0Y8d3uL01zDWFkxUjYyZ6rgCaAI2zZ1Wb34Oqtbx/nFZolPRDc8Xlm5A==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.5.0.tgz", + "integrity": "sha512-wcGvY31MpFNHIkUcXHHnvrE4IKYlpvitJw5P/1u892gMBAM46muQ+RH7UN1d+Ntnfx5apnOnVY6vcLmrWHOLwg==", "engines": { "node": ">= 0.4.0" } @@ -4402,27 +4741,6 @@ "node": ">= 6" } }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -4435,15 +4753,15 @@ } }, "node_modules/idtoken-verifier": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.1.0.tgz", - "integrity": "sha512-X0423UM4Rc5bFb39Ai0YHr35rcexlu4oakKdYzSGZxtoPy84P86hhAbzlpgbgomcLOFRgzgKRvhY7YjO5g8OPA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.2.2.tgz", + "integrity": "sha512-PFNivtWIUKFt0B53FOACLAM2PaejEwB/wh6fPqlWoLGMWP05JKGJyKyMv/uS9kduevEfRhHaSVdoLYUnQ0YmsA==", "dependencies": { - "base64-js": "^1.3.0", - "crypto-js": "^3.2.1", + "base64-js": "^1.5.1", + "crypto-js": "^4.1.1", "es6-promise": "^4.2.8", "jsbn": "^1.1.0", - "unfetch": "^4.1.0", + "unfetch": "^4.2.0", "url-join": "^4.0.1" } }, @@ -4472,15 +4790,18 @@ "dev": true }, "node_modules/import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-lazy": { @@ -4510,9 +4831,9 @@ } }, "node_modules/inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz", + "integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==", "engines": [ "node >= 0.4.0" ] @@ -4535,18 +4856,17 @@ } }, "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/inquirer": { @@ -4572,12 +4892,19 @@ "node": ">=8.0.0" } }, + "node_modules/inquirer/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==", + "engines": { + "node": ">=8" + } + }, "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { @@ -4588,9 +4915,9 @@ } }, "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4626,12 +4953,38 @@ "node": ">=8" } }, + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/inquirer/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -4648,6 +5001,19 @@ "node": ">=8" } }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4676,22 +5042,39 @@ } }, "node_modules/is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "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 + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { @@ -4701,19 +5084,30 @@ "node": ">=8" } }, - "node_modules/is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "engines": { "node": ">= 0.4" }, @@ -4733,6 +5127,18 @@ "is-ci": "bin.js" } }, + "node_modules/is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", @@ -4753,9 +5159,12 @@ } }, "node_modules/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -4801,25 +5210,31 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "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=", "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/is-generator-function": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", - "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, @@ -4828,30 +5243,21 @@ } }, "node_modules/is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, "dependencies": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-nan": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", @@ -4868,29 +5274,48 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-6.0.0.tgz", + "integrity": "sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==", "engines": { - "node": ">=0.12.0" + "node": ">=0.10.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-obj": { @@ -4903,21 +5328,21 @@ } }, "node_modules/is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "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, "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/is-plain-object": { @@ -4938,11 +5363,12 @@ "dev": true }, "node_modules/is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4951,28 +5377,32 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "dev": true, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true, + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -4981,11 +5411,11 @@ } }, "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dependencies": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4995,14 +5425,15 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.3.tgz", - "integrity": "sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", + "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", "dependencies": { - "available-typed-arrays": "^1.0.0", - "es-abstract": "^1.17.4", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", "foreach": "^2.0.5", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5016,6 +5447,17 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "node_modules/is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "dependencies": { + "call-bind": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -5065,9 +5507,9 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, "engines": { "node": ">=8" @@ -5141,6 +5583,26 @@ "node": ">= 8" } }, + "node_modules/istanbul-lib-processinfo/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/istanbul-lib-processinfo/node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -5247,9 +5709,9 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -5257,46 +5719,13 @@ "source-map": "^0.6.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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)", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/istanbul-lib-source-maps/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/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", + "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -5306,25 +5735,6 @@ "node": ">=8" } }, - "node_modules/iterate-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", - "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", - "dev": true - }, - "node_modules/iterate-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", - "dev": true, - "dependencies": { - "es-get-iterator": "^1.0.2", - "iterate-iterator": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", @@ -5334,45 +5744,55 @@ } }, "node_modules/joi": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.2.1.tgz", - "integrity": "sha512-YT3/4Ln+5YRpacdmfEfrrKh50/kkgX3LgBltjqnlMPIYiZ4hxXZuVJcxmsvxsdeHg9soZfE3qXxHC2tMpCCBOA==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.2.tgz", + "integrity": "sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw==", "dependencies": { - "@hapi/address": "^4.1.0", - "@hapi/formula": "^2.0.0", "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" } }, "node_modules/js-beautify": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.13.0.tgz", - "integrity": "sha512-/Tbp1OVzZjbwzwJQFIlYLm9eWQ+3aYbBXLSaqb1mEJzhcQAfrqMMQYtjb6io+U6KpD0ID4F+Id3/xcjH3l/sqA==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.0.tgz", + "integrity": "sha512-yuck9KirNSCAwyNJbqW+BxJqJ0NLJ4PwBUzQQACl5O3qHMBXVkXb/rD0ilh/Lat/tn88zSZ+CAHOlk0DsY7GuQ==", "dev": true, "dependencies": { "config-chain": "^1.1.12", "editorconfig": "^0.15.3", "glob": "^7.1.3", - "mkdirp": "^1.0.4", "nopt": "^5.0.0" }, "bin": { "css-beautify": "js/bin/css-beautify.js", "html-beautify": "js/bin/html-beautify.js", "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/js-beautify/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/js-beautify/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "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": ">=10" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/js-beautify/node_modules/nopt": { @@ -5401,9 +5821,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -5462,9 +5882,9 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dependencies": { "minimist": "^1.2.5" }, @@ -5505,19 +5925,6 @@ "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.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -5546,9 +5953,9 @@ } }, "node_modules/just-extend": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", - "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "node_modules/jwa": { @@ -5579,38 +5986,17 @@ } }, "node_modules/jwks-rsa/node_modules/axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "dependencies": { - "follow-redirects": "^1.10.0" - } - }, - "node_modules/jwks-rsa/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "follow-redirects": "^1.14.0" } }, - "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.14.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", - "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==", + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", + "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", "funding": [ { "type": "individual", @@ -5626,11 +6012,6 @@ } } }, - "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", @@ -5660,11 +6041,6 @@ "node": ">=0.10.0" } }, - "node_modules/kind-of/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/koalas": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz", @@ -5764,23 +6140,34 @@ "node": ">=4" } }, + "node_modules/load-json-file/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, + "engines": { + "node": ">=4" + } + }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "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": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", @@ -5859,12 +6246,11 @@ } }, "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { @@ -5875,9 +6261,9 @@ } }, "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5946,60 +6332,18 @@ "node": ">=0.10.0" } }, - "node_modules/log-utils/node_modules/ansi-colors": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz", - "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=", - "dependencies": { - "ansi-bgblack": "^0.1.1", - "ansi-bgblue": "^0.1.1", - "ansi-bgcyan": "^0.1.1", - "ansi-bggreen": "^0.1.1", - "ansi-bgmagenta": "^0.1.1", - "ansi-bgred": "^0.1.1", - "ansi-bgwhite": "^0.1.1", - "ansi-bgyellow": "^0.1.1", - "ansi-black": "^0.1.1", - "ansi-blue": "^0.1.1", - "ansi-bold": "^0.1.1", - "ansi-cyan": "^0.1.1", - "ansi-dim": "^0.1.1", - "ansi-gray": "^0.1.1", - "ansi-green": "^0.1.1", - "ansi-grey": "^0.1.1", - "ansi-hidden": "^0.1.1", - "ansi-inverse": "^0.1.1", - "ansi-italic": "^0.1.1", - "ansi-magenta": "^0.1.1", - "ansi-red": "^0.1.1", - "ansi-reset": "^0.1.1", - "ansi-strikethrough": "^0.1.1", - "ansi-underline": "^0.1.1", - "ansi-white": "^0.1.1", - "ansi-yellow": "^0.1.1", - "lazy-cache": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", + "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", "dependencies": { "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", "fecha": "^4.2.0", "ms": "^2.1.1", + "safe-stable-stringify": "^1.1.0", "triple-beam": "^1.3.0" } }, - "node_modules/logform/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/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -6060,9 +6404,9 @@ } }, "node_modules/luxon": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz", - "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==", + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", + "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==", "engines": { "node": "*" } @@ -6111,21 +6455,27 @@ } }, "node_modules/memoizee": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", - "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "dev": true, "dependencies": { - "d": "1", - "es5-ext": "^0.10.45", - "es6-weak-map": "^2.0.2", + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.5" + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" } }, + "node_modules/memoizee/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 + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -6156,19 +6506,19 @@ } }, "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "dependencies": { - "mime-db": "1.44.0" + "mime-db": "1.50.0" }, "engines": { "node": ">= 0.6" @@ -6239,36 +6589,36 @@ } }, "node_modules/mocha": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.3.tgz", - "integrity": "sha512-ZbaYib4hT4PpF4bdSO2DohooKXIn4lDeiYqB+vTmCdr6l2woW0b6H3pf5x4sM5nwQMru9RvjjHYWVGltR50ZBw==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "dev": true, "dependencies": { + "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.2", - "debug": "4.1.1", - "diff": "4.0.2", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", + "js-yaml": "4.0.0", "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "object.assign": "4.1.0", - "promise.allsettled": "1.0.2", - "serialize-javascript": "4.0.0", - "strip-json-comments": "3.0.1", - "supports-color": "7.1.0", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.0", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.1" + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -6282,97 +6632,49 @@ "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/debug": { + "node_modules/mocha/node_modules/ansi-colors": { "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)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/mocha/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/mocha/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==", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/mocha/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" - } + "node_modules/mocha/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/mocha/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==", + "node_modules/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "ms": "2.1.2" }, "engines": { - "node": ">=10" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/mocha/node_modules/ms": { + "node_modules/mocha/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==", "dev": true }, - "node_modules/mocha/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "node_modules/mocha/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, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { "node": ">=10" }, @@ -6380,58 +6682,60 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/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==", + "node_modules/mocha/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "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": ">=10" + "node": "*" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/path-exists": { + "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/mocha/node_modules/strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/mocha/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/mocha/node_modules/which": { @@ -6469,9 +6773,9 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/murmur-hash-js": { "version": "1.0.0", @@ -6480,9 +6784,9 @@ "dev": true }, "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "node_modules/mv": { "version": "2.1.1", @@ -6498,40 +6802,24 @@ "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": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "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/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "optional": true }, - "node_modules/mv/node_modules/rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "optional": true, - "dependencies": { - "glob": "^6.0.1" - }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, "bin": { - "rimraf": "bin.js" + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "optional": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6581,9 +6869,9 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node_modules/nise": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", - "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0", @@ -6644,6 +6932,12 @@ "node": ">=8" } }, + "node_modules/node-releases": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "dev": true + }, "node_modules/node-schedule": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.0.0.tgz", @@ -6658,9 +6952,9 @@ } }, "node_modules/nodemon": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", - "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.14.tgz", + "integrity": "sha512-frcpDx+PviKEQRSYzwhckuO2zoHcBYLHI754RE9z5h1RGtrngerc04mLpQQCPWBkH/2ObrX7We9YiwVSYZpFJQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -6672,8 +6966,8 @@ "semver": "^5.7.1", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^4.0.0" + "undefsafe": "^2.0.3", + "update-notifier": "^5.1.0" }, "bin": { "nodemon": "bin/nodemon.js" @@ -6687,30 +6981,14 @@ } }, "node_modules/nodemon/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "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)", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, - "node_modules/nodemon/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/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -6738,15 +7016,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6757,9 +7026,9 @@ } }, "node_modules/normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true, "engines": { "node": ">=8" @@ -6806,13 +7075,21 @@ "node": ">=8.9" } }, + "node_modules/nyc/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" + } + }, "node_modules/nyc/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { @@ -6822,6 +7099,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/nyc/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -6851,6 +7137,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nyc/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -6864,6 +7159,35 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -6903,24 +7227,6 @@ "node": ">=8" } }, - "node_modules/nyc/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/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/nyc/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -6945,13 +7251,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/nyc/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -6971,6 +7291,12 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, "node_modules/nyc/node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", @@ -7090,9 +7416,9 @@ } }, "node_modules/object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7117,12 +7443,12 @@ } }, "node_modules/object.assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", - "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dependencies": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.0", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" }, @@ -7133,55 +7459,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.assign/node_modules/es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", "dev": true, "dependencies": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "has": "^1.0.3" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", - "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", "dev": true, "dependencies": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" @@ -7191,15 +7491,14 @@ } }, "node_modules/object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "dependencies": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" }, "engines": { "node": ">= 0.4" @@ -7283,27 +7582,33 @@ } }, "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "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": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "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": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -7319,12 +7624,12 @@ } }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/package-hash": { @@ -7403,12 +7708,12 @@ } }, "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=", + "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": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { @@ -7428,9 +7733,9 @@ } }, "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-to-regexp": { @@ -7451,9 +7756,9 @@ } }, "node_modules/pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, "engines": { "node": "*" @@ -7465,15 +7770,15 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "node_modules/pg": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.4.0.tgz", - "integrity": "sha512-01LcNrAf+mBI46c78mE86I5o5KkOM942lLiSBdiCfgHTR+oUNIjh1fKClWeoPNHJz2oXe/VUSqtk1vwAQYwWEg==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz", + "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==", "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.4.0", - "pg-pool": "^3.2.1", - "pg-protocol": "^1.3.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.4.1", + "pg-protocol": "^1.5.0", "pg-types": "^2.1.0", "pgpass": "1.x" }, @@ -7490,16 +7795,16 @@ } }, "node_modules/pg-connection-string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", - "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" }, "node_modules/pg-hstore": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.3.tgz", - "integrity": "sha512-qpeTpdkguFgfdoidtfeTho1Q1zPVPbtMHgs8eQ+Aan05iLmIs3Z3oo5DOZRclPGoQ4i68I1kCtQSJSa7i0ZVYg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz", + "integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==", "dependencies": { - "underscore": "^1.7.0" + "underscore": "^1.13.1" }, "engines": { "node": ">= 0.8.x" @@ -7514,17 +7819,17 @@ } }, "node_modules/pg-pool": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", - "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz", + "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==", "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.3.0.tgz", - "integrity": "sha512-64/bYByMrhWULUaCd+6/72c9PMWhiVFs3EVxl9Ct6a3v/U8+rKgqP2w+kKg/BIGgMJyB+Bk/eNivT32Al+Jghw==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" }, "node_modules/pg-types": { "version": "2.2.0", @@ -7542,17 +7847,23 @@ } }, "node_modules/pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", "dependencies": { - "split": "^1.0.0" + "split2": "^3.1.1" } }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true, "engines": { "node": ">=8.6" @@ -7651,15 +7962,6 @@ "node": ">=6" } }, - "node_modules/pkg-conf/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/pkg-conf/node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -7673,6 +7975,15 @@ "node": ">=4" } }, + "node_modules/pkg-conf/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" + } + }, "node_modules/pkg-conf/node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -7682,6 +7993,15 @@ "node": ">=6" } }, + "node_modules/pkg-conf/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, + "engines": { + "node": ">=4" + } + }, "node_modules/pkg-conf/node_modules/type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", @@ -7706,42 +8026,94 @@ } }, "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "find-up": "^2.1.0" + "find-up": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/pointer-symbol": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pointer-symbol/-/pointer-symbol-1.0.0.tgz", - "integrity": "sha1-YPkRAgTqepKbYmRKITFVQ8uz1Ec=", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/postgres-date": { + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pointer-symbol": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pointer-symbol/-/pointer-symbol-1.0.0.tgz", + "integrity": "sha1-YPkRAgTqepKbYmRKITFVQ8uz1Ec=", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", @@ -7810,25 +8182,6 @@ "node": ">=0.4.0" } }, - "node_modules/promise.allsettled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", - "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", - "dev": true, - "dependencies": { - "array.prototype.map": "^1.0.1", - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "iterate-value": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/prompt-actions": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/prompt-actions/-/prompt-actions-3.0.2.tgz", @@ -7840,6 +8193,19 @@ "node": ">=4" } }, + "node_modules/prompt-actions/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/prompt-actions/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/prompt-base": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/prompt-base/-/prompt-base-4.1.0.tgz", @@ -7867,11 +8233,6 @@ "ms": "^2.1.1" } }, - "node_modules/prompt-base/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/prompt-choices": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/prompt-choices/-/prompt-choices-4.1.0.tgz", @@ -7923,14 +8284,6 @@ "node": ">=0.10.0" } }, - "node_modules/prompt-choices/node_modules/is-number": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-6.0.0.tgz", - "integrity": "sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prompt-choices/node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -7995,11 +8348,6 @@ "node": ">=0.10.0" } }, - "node_modules/prompt-question/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/prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", @@ -8018,17 +8366,17 @@ "dev": true }, "node_modules/protocol-buffers-schema": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz", - "integrity": "sha512-YVCvdhxWNDP8/nJDyXLuM+UFsuPk4+1PB7WGPVDzm3HTHbzFLxQYeW2iZpS4mmnXrQJGBzt230t/BbEb7PrQaw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", "dev": true }, "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" }, "engines": { @@ -8074,9 +8422,9 @@ } }, "node_modules/pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dev": true, "dependencies": { "escape-goat": "^2.0.0" @@ -8086,11 +8434,17 @@ } }, "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/querystring": { @@ -8102,6 +8456,26 @@ "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" + } + ] + }, "node_modules/r7insight_node": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/r7insight_node/-/r7insight_node-1.8.4.tgz", @@ -8192,6 +8566,12 @@ "rc": "cli.js" } }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -8234,84 +8614,126 @@ "node": ">=4" } }, - "node_modules/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==", + "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": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "locate-path": "^2.0.0" }, "engines": { - "node": ">= 6" + "node": ">=4" } }, - "node_modules/readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "node_modules/read-pkg-up/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, "dependencies": { - "picomatch": "^2.2.1" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=4" } }, - "node_modules/readline-ui": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/readline-ui/-/readline-ui-2.2.3.tgz", - "integrity": "sha512-ix7jz0PxqQqcIuq3yQTHv1TOhlD2IHO74aNO+lSuXsRYm1d+pdyup1yF3zKyLK1wWZrVNGjkzw5tUegO2IDy+A==", + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, "dependencies": { - "component-emitter": "^1.2.1", - "debug": "^2.6.8", - "readline-utils": "^2.2.1", - "string-width": "^2.0.0" + "p-try": "^1.0.0" }, "engines": { - "node": ">=4.0" + "node": ">=4" } }, - "node_modules/readline-ui/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "node_modules/read-pkg-up/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, + "dependencies": { + "p-limit": "^1.1.0" + }, "engines": { "node": ">=4" } }, - "node_modules/readline-ui/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, "engines": { "node": ">=4" } }, - "node_modules/readline-ui/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/read-pkg-up/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" + } + }, + "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": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "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/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" }, "engines": { - "node": ">=4" + "node": ">=8.10.0" } }, - "node_modules/readline-ui/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "node_modules/readline-ui": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/readline-ui/-/readline-ui-2.2.3.tgz", + "integrity": "sha512-ix7jz0PxqQqcIuq3yQTHv1TOhlD2IHO74aNO+lSuXsRYm1d+pdyup1yF3zKyLK1wWZrVNGjkzw5tUegO2IDy+A==", "dependencies": { - "ansi-regex": "^3.0.0" + "component-emitter": "^1.2.1", + "debug": "^2.6.8", + "readline-utils": "^2.2.1", + "string-width": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=4.0" + } + }, + "node_modules/readline-ui/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, + "node_modules/readline-ui/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/readline-utils": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/readline-utils/-/readline-utils-2.2.3.tgz", @@ -8331,11 +8753,6 @@ "node": ">=4.0" } }, - "node_modules/readline-utils/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/readline-utils/node_modules/is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -8347,11 +8764,6 @@ "node": ">=0.10.0" } }, - "node_modules/readline-utils/node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" - }, "node_modules/reconnect-core": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/reconnect-core/-/reconnect-core-1.3.0.tgz", @@ -8369,9 +8781,9 @@ } }, "node_modules/registry-auth-token": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", - "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "dependencies": { "rc": "^1.2.8" @@ -8481,11 +8893,12 @@ "dev": true }, "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { @@ -8521,6 +8934,14 @@ "node": ">=8" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, "node_modules/retry-as-promised": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", @@ -8538,11 +8959,12 @@ } }, "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^6.0.1" }, "bin": { "rimraf": "bin.js" @@ -8557,19 +8979,36 @@ } }, "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "node_modules/rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { + "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" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { "npm": ">=2.0.0" } }, @@ -8584,6 +9023,11 @@ "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", "optional": true }, + "node_modules/safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -8595,19 +9039,16 @@ "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, "node_modules/secure-json-parse": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.1.0.tgz", - "integrity": "sha512-GckO+MS/wT4UogDyoI/H/S1L0MCcKS1XX/vp48wfmU7Nw4woBmb8mIpu4zPBQjKlRT88/bt9xdoV4111jPpNJA==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.4.0.tgz", + "integrity": "sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==" }, "node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "semver": "bin/semver" } }, "node_modules/semver-diff": { @@ -8654,20 +9095,33 @@ "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": { + "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/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/sequelize": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.3.5.tgz", - "integrity": "sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.7.0.tgz", + "integrity": "sha512-OVw3psUggqQT9kYg5Z9fja/BMdBxX/Ua3Bwx2yif5g6QuYEE4UfWq5jW6LmbacGwgK6bgZs05Q2zCkJZCDFrSA==", "dependencies": { "debug": "^4.1.1", "dottie": "^2.0.0", - "inflection": "1.12.0", - "lodash": "^4.17.15", + "inflection": "1.13.1", + "lodash": "^4.17.20", "moment": "^2.26.0", "moment-timezone": "^0.5.31", "retry-as-promised": "^3.2.0", @@ -8675,7 +9129,7 @@ "sequelize-pool": "^6.0.0", "toposort-class": "^1.0.1", "uuid": "^8.1.0", - "validator": "^10.11.0", + "validator": "^13.6.0", "wkx": "^0.5.0" }, "engines": { @@ -8724,6 +9178,185 @@ "node": ">=10.0.0" } }, + "node_modules/sequelize-cli/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/sequelize-cli/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sequelize-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/sequelize-cli/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sequelize-cli/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/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" + } + }, + "node_modules/sequelize-cli/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sequelize-cli/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/sequelize-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/sequelize-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, "node_modules/sequelize-pool": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz", @@ -8732,31 +9365,40 @@ "node": ">= 10.0.0" } }, - "node_modules/sequelize/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/sequelize/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==", "dependencies": { - "ms": "2.1.2" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=10" + } + }, + "node_modules/sequelize/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/sequelize/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/sequelize/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/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -8783,9 +9425,9 @@ "dev": true }, "node_modules/set-getter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", - "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", + "integrity": "sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==", "dependencies": { "to-object-path": "^0.3.0" }, @@ -8862,14 +9504,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel/node_modules/object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", @@ -8877,9 +9511,9 @@ "dev": true }, "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "node_modules/simple-lru-cache": { "version": "0.0.2", @@ -8895,21 +9529,15 @@ "is-arrayish": "^0.3.1" } }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, "node_modules/sinon": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.0.tgz", - "integrity": "sha512-eSNXz1XMcGEMHw08NJXSyTHIu6qTCOiN8x9ODACmZpNQpr0aXTBXBnI4xTzQzR+TEpOmLiKowGf9flCuKIzsbw==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/formatio": "^5.0.1", - "@sinonjs/samsam": "^5.2.0", + "@sinonjs/samsam": "^5.3.1", "diff": "^4.0.2", "nise": "^4.0.4", "supports-color": "^7.1.0" @@ -8919,10 +9547,19 @@ "url": "https://opencollective.com/sinon" } }, - "node_modules/sinon/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==", + "node_modules/sinon/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/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" @@ -8953,23 +9590,15 @@ "node": ">=6" } }, - "node_modules/slice-ansi/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, "node_modules/sorted-array-functions": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==" }, "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" @@ -8992,6 +9621,26 @@ "node": ">=8" } }, + "node_modules/spawn-wrap/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/spawn-wrap/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -9049,20 +9698,30 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", - "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/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==", "dependencies": { - "through": "2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": "*" + "node": ">= 6" } }, "node_modules/sprintf-js": { @@ -9185,11 +9844,6 @@ "node": ">=0.10.0" } }, - "node_modules/static-extend/node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "node_modules/static-extend/node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -9247,106 +9901,67 @@ "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" }, "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==", + "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.2.0" + "safe-buffer": "~5.1.0" } }, - "node_modules/string_decoder/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" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dependencies": { - "ansi-regex": "^5.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dependencies": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^3.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-color": { @@ -9369,9 +9984,9 @@ } }, "node_modules/stripe": { - "version": "8.168.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.168.0.tgz", - "integrity": "sha512-MQXTarijIOagtLajGe1zBFc9KMbB7jIoFv/kr1WsDPJO/S+/hhZjsXCgBkNvnlwK7Yl0VUn+YrgXl9/9wU6WCw==", + "version": "8.183.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.183.0.tgz", + "integrity": "sha512-QcM3nimH1CuP49VPPRt36Wgfu4QoS+Wm0eyGMis7Ej+seWFKqMffMdx7TE2gn8dVsJIOA1kDuIbAQGqpZHozGA==", "dependencies": { "@types/node": ">=8.1.0", "qs": "^6.6.0" @@ -9409,27 +10024,34 @@ "node": ">= 7.0.0" } }, - "node_modules/superagent/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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)", + "node_modules/superagent/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dependencies": { - "ms": "2.1.2" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=6.0" + "node": ">= 6" + } + }, + "node_modules/superagent/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==", + "dependencies": { + "yallist": "^4.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "engines": { + "node": ">=10" } }, "node_modules/superagent/node_modules/mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", "bin": { "mime": "cli.js" }, @@ -9437,22 +10059,38 @@ "node": ">=4.0.0" } }, - "node_modules/superagent/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/superagent/node_modules/qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "node_modules/superagent/node_modules/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==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, "engines": { - "node": ">=0.6" + "node": ">= 6" + } + }, + "node_modules/superagent/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, + "node_modules/superagent/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/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -9478,19 +10116,19 @@ "node": ">=6.0.0" } }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "engines": { + "node": ">=6" + } + }, "node_modules/table/node_modules/emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, - "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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, "node_modules/table/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -9504,6 +10142,17 @@ "node": ">=6" } }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tc-core-library-js": { "version": "2.4.0", "resolved": "git+ssh://git@github.com/appirio-tech/tc-core-library-js.git#d16413db30b1eed21c0cf426e185bedb2329ddab", @@ -9533,6 +10182,14 @@ "follow-redirects": "0.0.7" } }, + "node_modules/tc-core-library-js/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/tc-core-library-js/node_modules/follow-redirects": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", @@ -9542,17 +10199,10 @@ "stream-consume": "^0.1.0" } }, - "node_modules/term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/tc-core-library-js/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/terminal-paginator": { "version": "2.0.2", @@ -9567,6 +10217,19 @@ "node": ">=0.10.0" } }, + "node_modules/terminal-paginator/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/terminal-paginator/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -9581,6 +10244,26 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -9666,6 +10349,15 @@ "node": ">=8.0" } }, + "node_modules/to-regex-range/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/toggle-array": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toggle-array/-/toggle-array-1.0.1.tgz", @@ -9735,9 +10427,9 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "node_modules/tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -9811,9 +10503,9 @@ } }, "node_modules/uglify-js": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.0.tgz", - "integrity": "sha512-R/tiGB1ZXp2BC+TkRGLwj8xUZgdfT2f4UZEgX6aVjJ5uttPrr4fYmwTWDGqVnBCLbOXRMY6nr/BTbwCtVfps0g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", "dev": true, "optional": true, "bin": { @@ -9835,19 +10527,30 @@ "node": ">=6.0.0" } }, - "node_modules/undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "dependencies": { - "debug": "^2.2.0" + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "node_modules/underscore": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz", - "integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", + "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" }, "node_modules/unfetch": { "version": "4.2.0", @@ -9890,39 +10593,39 @@ } }, "node_modules/update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", "dev": true, "dependencies": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", + "boxen": "^5.0.0", + "chalk": "^4.1.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, "node_modules/update-notifier/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { @@ -9933,16 +10636,19 @@ } }, "node_modules/update-notifier/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/update-notifier/node_modules/color-convert": { @@ -9972,6 +10678,33 @@ "node": ">=8" } }, + "node_modules/update-notifier/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/update-notifier/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/update-notifier/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9984,14 +10717,25 @@ "node": ">=8" } }, + "node_modules/update-notifier/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dependencies": { "punycode": "^2.1.0" } }, + "node_modules/urijs": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.7.tgz", + "integrity": "sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==" + }, "node_modules/url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", @@ -10024,9 +10768,9 @@ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, "node_modules/util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -10050,17 +10794,17 @@ } }, "node_modules/uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -10073,9 +10817,9 @@ } }, "node_modules/validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz", + "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==", "engines": { "node": ">= 0.10" } @@ -10101,6 +10845,11 @@ "extsprintf": "^1.2.0" } }, + "node_modules/verror/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=" + }, "node_modules/warning-symbol": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/warning-symbol/-/warning-symbol-0.1.0.tgz", @@ -10120,6 +10869,21 @@ "which": "bin/which" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -10127,16 +10891,16 @@ "dev": true }, "node_modules/which-typed-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.2.tgz", - "integrity": "sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", + "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", "dependencies": { - "available-typed-arrays": "^1.0.2", - "es-abstract": "^1.17.5", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" }, "engines": { "node": ">= 0.4" @@ -10154,56 +10918,57 @@ "string-width": "^1.0.2 || 2" } }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/wide-align/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "node_modules/widest-line/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": ">=4" + "node": ">=8" } }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/widest-line/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "node_modules/widest-line/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, "dependencies": { - "string-width": "^4.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -10271,26 +11036,17 @@ "node": ">= 6.4.0" } }, - "node_modules/winston-transport/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/winston-transport/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==", + "node_modules/winston/node_modules/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==", "dependencies": { - "safe-buffer": "~5.1.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/wkx": { @@ -10316,52 +11072,103 @@ "dev": true }, "node_modules/workerpool": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", - "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", "dev": true }, "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "node_modules/wrap-ansi/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" + } + }, + "node_modules/wrap-ansi/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/wrap-ansi/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": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/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/wrap-ansi/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" + } + }, + "node_modules/wrap-ansi/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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/wrappy": { @@ -10436,10 +11243,13 @@ } }, "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/yallist": { "version": "2.1.2", @@ -10447,510 +11257,378 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "engines": { + "node": ">=10" } }, "node_modules/yargs-unparser": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", - "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "dependencies": { - "camelcase": "^5.3.1", - "decamelize": "^1.2.0", - "flat": "^4.1.0", - "is-plain-obj": "^1.1.0", - "yargs": "^14.2.3" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/yargs-unparser/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/yargs-unparser/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/yargs/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, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-unparser/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs-unparser/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-unparser/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/yargs-unparser/node_modules/p-locate": { + "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-unparser/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-unparser/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-unparser/node_modules/yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - } - }, - "node_modules/yargs-unparser/node_modules/yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "node": ">=8" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "locate-path": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/yargs/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, "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "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, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } } }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.14.5" } }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, "@babel/core": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.6.tgz", - "integrity": "sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.6", - "@babel/helper-module-transforms": "^7.11.0", - "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.11.5", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.11.5", - "@babel/types": "^7.11.5", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "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==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } }, "@babel/generator": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", - "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, "requires": { - "@babel/types": "^7.11.5", + "@babel/types": "^7.15.6", "jsesc": "^2.5.1", "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", - "lodash": "^4.17.19" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" } }, "@babel/helper-optimise-call-expression": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", - "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" } }, "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.15.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.15.4" } }, "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==" + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true }, "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/traverse": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", - "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.5", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.5", - "@babel/types": "^7.11.5", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true - }, - "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 } } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" } }, @@ -10976,14 +11654,6 @@ "secure-json-parse": "^2.1.0" }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "requires": { - "ms": "2.1.2" - } - }, "decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -10996,41 +11666,18 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, - "@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==" - }, "@hapi/hoek": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.0.tgz", - "integrity": "sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw==" - }, - "@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz", + "integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw==" }, "@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "requires": { "@hapi/hoek": "^9.0.0" } @@ -11048,6 +11695,12 @@ "resolve-from": "^5.0.0" }, "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -11085,18 +11738,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "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 - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -11106,29 +11747,47 @@ } }, "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, "@joi/date": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@joi/date/-/date-2.0.1.tgz", - "integrity": "sha512-vAnBxaPmyXRmHlbr5H3zY6x8ToW1a3c3gCo91dsf/HPKP2vS4sz2xzjyCE1up0vmFmSWgfDIyJMpRWVOG2cpZQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@joi/date/-/date-2.1.0.tgz", + "integrity": "sha512-2zN5m0LgxZp/cynHGbzEImVmFIa+n+IOb/Nlw5LX/PLJneeCwG1NbiGw7MvPjsAKUGQK8z31Nn6V6lEN+4fZhg==", "requires": { "moment": "2.x.x" } }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "@sideway/address": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", + "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, "@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -11143,20 +11802,10 @@ "@sinonjs/commons": "^1.7.0" } }, - "@sinonjs/formatio": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", - "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^5.0.2" - } - }, "@sinonjs/samsam": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz", - "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -11202,16 +11851,6 @@ "ms": "^2.1.1" } }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "joi": { "version": "13.7.0", "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", @@ -11222,33 +11861,6 @@ "topo": "3.x.x" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "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.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" - } - }, - "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.0" - } - }, "superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -11289,31 +11901,26 @@ "dev": true }, "@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==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", "requires": { "@types/connect": "*", "@types/node": "*" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, "@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==", + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "requires": { "@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==", + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -11331,9 +11938,9 @@ } }, "@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==", + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", + "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -11341,17 +11948,17 @@ } }, "@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==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.2.tgz", + "integrity": "sha512-Q74UyYRX/zIgl1HSp9tUX2PlG8glkVm+59r7aK4KGKzC5jqKIOX6rrVLRQrzpZUQ84VukHtRoeAuon2nIssHPQ==", "requires": { "@types/express": "*" } }, "@types/lodash": { - "version": "4.14.172", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", - "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==", + "version": "4.14.175", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz", + "integrity": "sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw==", "dev": true }, "@types/mime": { @@ -11360,29 +11967,35 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/node": { - "version": "14.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", - "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==" + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", + "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" }, "@types/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==" + "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==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@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==", + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", "requires": { "@types/mime": "^1", "@types/node": "*" } }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -11399,14 +12012,14 @@ } }, "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "requires": {} }, "agent-base": { @@ -11415,21 +12028,6 @@ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "requires": { "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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==" - } } }, "aggregate-error": { @@ -11443,9 +12041,9 @@ } }, "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "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.1", "fast-json-stable-stringify": "^2.0.0", @@ -11454,35 +12052,44 @@ } }, "ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, "requires": { - "string-width": "^3.0.0" + "string-width": "^4.1.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "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 }, "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=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "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": "^5.0.1" } } } @@ -11576,10 +12183,38 @@ } }, "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz", + "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=", + "requires": { + "ansi-bgblack": "^0.1.1", + "ansi-bgblue": "^0.1.1", + "ansi-bgcyan": "^0.1.1", + "ansi-bggreen": "^0.1.1", + "ansi-bgmagenta": "^0.1.1", + "ansi-bgred": "^0.1.1", + "ansi-bgwhite": "^0.1.1", + "ansi-bgyellow": "^0.1.1", + "ansi-black": "^0.1.1", + "ansi-blue": "^0.1.1", + "ansi-bold": "^0.1.1", + "ansi-cyan": "^0.1.1", + "ansi-dim": "^0.1.1", + "ansi-gray": "^0.1.1", + "ansi-green": "^0.1.1", + "ansi-grey": "^0.1.1", + "ansi-hidden": "^0.1.1", + "ansi-inverse": "^0.1.1", + "ansi-italic": "^0.1.1", + "ansi-magenta": "^0.1.1", + "ansi-red": "^0.1.1", + "ansi-reset": "^0.1.1", + "ansi-strikethrough": "^0.1.1", + "ansi-underline": "^0.1.1", + "ansi-white": "^0.1.1", + "ansi-yellow": "^0.1.1", + "lazy-cache": "^2.0.1" + } }, "ansi-cyan": { "version": "0.1.1", @@ -11598,17 +12233,17 @@ } }, "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "requires": { - "type-fest": "^0.11.0" + "type-fest": "^0.21.3" }, "dependencies": { "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" } } }, @@ -11677,9 +12312,9 @@ } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-reset": { "version": "0.1.1", @@ -11740,9 +12375,9 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -11795,37 +12430,22 @@ } } }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" - } - }, - "array.prototype.map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.2.tgz", - "integrity": "sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.4" + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" } }, "asn1": { @@ -11853,9 +12473,24 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" + }, + "async-mutex": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz", + "integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==", + "requires": { + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } }, "asynckit": { "version": "0.4.0", @@ -11863,25 +12498,35 @@ "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==", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.17.0.tgz", + "integrity": "sha512-rqHhOq6ZgOaHwz0e46YywsGW4Y2wLF3Fu+y2wT94vbEFNAi5vyJHJYVyNAetAN7w7Ljhda/7SsUs/usuEMRBpQ==", "requires": { - "base64-js": "^1.3.0", - "idtoken-verifier": "^2.0.3", + "base64-js": "^1.5.1", + "idtoken-verifier": "^2.2.2", "js-cookie": "^2.2.0", - "qs": "^6.7.0", + "qs": "^6.10.1", "superagent": "^5.3.1", "url-join": "^4.0.1", "winchan": "^0.2.2" }, "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "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": { - "ms": "2.1.2" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "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" } }, "mime": { @@ -11889,10 +12534,23 @@ "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==" + "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" + } + }, + "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" + } }, "superagent": { "version": "5.3.1", @@ -11910,32 +12568,24 @@ "qs": "^6.9.4", "readable-stream": "^3.6.0", "semver": "^7.3.2" - }, - "dependencies": { - "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" - } - } } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "available-typed-arrays": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", - "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", - "requires": { - "array-filter": "^1.0.0" - } + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" }, "aws-sdk": { - "version": "2.787.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.787.0.tgz", - "integrity": "sha512-3WlUdWqUB8Vhdvj/7TENr/7SEmQzxmnHxOJ8l2WjZbcMRSuI0/9Ym4p1TC3hf21VDVDhkdGlw60QqpZQ1qb+Mg==", + "version": "2.1011.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1011.0.tgz", + "integrity": "sha512-U5CDmLUHYAur89+Rx1r3X5gRzc8ib90G9aaKnyGqLsIail24r6UINejJB8pyOzFQ+u22/kFKKclfXcTj/Hflbg==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -11990,14 +12640,14 @@ } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "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==" + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -12019,9 +12669,9 @@ } }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bluebird": { @@ -12045,6 +12695,26 @@ "qs": "6.7.0", "raw-body": "2.4.0", "type-is": "~1.6.17" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } } }, "bottleneck": { @@ -12053,35 +12723,40 @@ "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", "dev": true, "requires": { "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { + "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 + }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "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": "^4.1.0", @@ -12109,6 +12784,32 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "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": "^5.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12117,6 +12818,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "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 } } }, @@ -12144,6 +12851,19 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "browserslist": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", + "escalade": "^3.1.1", + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" + } + }, "buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -12245,9 +12965,15 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001270", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001270.tgz", + "integrity": "sha512-TcIC7AyNWXhcOmv2KftOl1ShFAaHQYcB/EPL/hEyMrcS7ZX0/DvV1aoy6BzV0+16wTpoAyTMGDNAJfSqS/rz7A==", "dev": true }, "caseless": { @@ -12256,16 +12982,16 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "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", + "pathval": "^1.1.1", "type-detect": "^4.0.5" } }, @@ -12298,22 +13024,37 @@ "ansi-dim": "^0.1.1", "debug": "^2.6.6", "strip-color": "^0.1.0" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" } }, "ci-info": { @@ -12370,37 +13111,46 @@ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "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 }, "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=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "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": "^5.0.1" } } } @@ -12479,9 +13229,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -12532,21 +13282,29 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "config": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/config/-/config-3.3.2.tgz", - "integrity": "sha512-NlGfBn2565YA44Irn7GV5KHlIGC3KJbf0062/zW5ddP9VXIuRj0m7HVyFAWvMZvaHPEglyGfwmevGz3KosIpCg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/config/-/config-3.3.6.tgz", + "integrity": "sha512-Hj5916C5HFawjYJat1epbyY2PlAgLpBtDUlr0MxGLgo3p5+7kylyvnRY18PqJHgnNWXcdd0eWDemT7eYWuFgwg==", "requires": { "json5": "^2.1.1" } }, "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, "requires": { "ini": "^1.3.4", "proto-list": "~1.2.1" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + } } }, "configstore": { @@ -12589,9 +13347,9 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -12608,9 +13366,9 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" }, "copy-descriptor": { "version": "0.1.1", @@ -12623,9 +13381,9 @@ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "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=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cors": { "version": "2.8.5", @@ -12637,12 +13395,12 @@ } }, "cron-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.3.0.tgz", - "integrity": "sha512-Tz5WxSrDVhR7YVuLuUxhXoMGHCWoe8I7g8APkyRZNaINXHQ3zcfK97av6hBYy9ue4sOLI7ZH7SeQqi/t4jR+5A==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.5.0.tgz", + "integrity": "sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==", "requires": { - "is-nan": "^1.3.0", - "luxon": "^1.25.0" + "is-nan": "^1.3.2", + "luxon": "^1.26.0" } }, "cross-spawn": { @@ -12655,19 +13413,12 @@ "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } } }, "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==" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" }, "crypto-random-string": { "version": "2.0.0", @@ -12703,16 +13454,23 @@ } }, "date-fns": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", - "integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==" + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz", + "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==" }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { - "ms": "2.0.0" + "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==" + } } }, "debug-log": { @@ -12722,9 +13480,9 @@ "dev": true }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "decompress-response": { @@ -12752,9 +13510,9 @@ "dev": true }, "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=" + "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==" }, "default-require-extensions": { "version": "3.0.0", @@ -12763,14 +13521,6 @@ "dev": true, "requires": { "strip-bom": "^4.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - } } }, "defer-to-connect": { @@ -12809,6 +13559,20 @@ "uniq": "^1.0.1" }, "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", @@ -12833,9 +13597,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "doctrine": { @@ -12856,9 +13620,9 @@ } }, "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" }, "dottie": { "version": "2.0.2", @@ -12918,12 +13682,6 @@ "pseudomap": "^1.0.2", "yallist": "^2.1.2" } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true } } }, @@ -12932,6 +13690,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "electron-to-chromium": { + "version": "1.3.873", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.873.tgz", + "integrity": "sha512-TiHlCgl2uP26Z0c67u442c0a2MZCWZNCRnPTQDPhVJ4h9G6z2zU0lApD9H0K9R5yFL5SfdaiVsVD2izOY24xBQ==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -12962,6 +13726,14 @@ "dev": true, "requires": { "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } } }, "error-symbol": { @@ -12970,50 +13742,30 @@ "integrity": "sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y=" }, "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "dev": true, - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -13081,6 +13833,12 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", @@ -13141,23 +13899,23 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "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==" + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } } } }, @@ -13176,23 +13934,104 @@ "requires": {} }, "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", "dev": true, "requires": { - "debug": "^2.6.9", + "debug": "^3.2.7", + "find-up": "^2.1.0", "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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": { + "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" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "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" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "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 + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } } }, "eslint-plugin-es": { @@ -13206,9 +14045,9 @@ }, "dependencies": { "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true } } @@ -13232,6 +14071,15 @@ "resolve": "^1.11.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" + } + }, "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", @@ -13241,6 +14089,12 @@ "esutils": "^2.0.2", "isarray": "^1.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -13307,9 +14161,9 @@ } }, "eslint-plugin-standard": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", - "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", + "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==", "dev": true, "requires": {} }, @@ -13351,9 +14205,9 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "requires": { "estraverse": "^5.1.0" }, @@ -13445,6 +14299,26 @@ "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + } } }, "express-interceptor": { @@ -13453,21 +14327,36 @@ "integrity": "sha1-M0YKjhHc5+WgIsr1VdN35F3bgio=", "requires": { "debug": "^2.2.0" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", "dev": true, "requires": { - "type": "^2.0.0" + "type": "^2.5.0" }, "dependencies": { "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", "dev": true } } @@ -13516,14 +14405,14 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "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==" + "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==" }, "fecha": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", - "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", + "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" }, "figures": { "version": "3.2.0", @@ -13562,77 +14451,32 @@ "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "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 - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } } }, "find-root": { @@ -13642,22 +14486,20 @@ "dev": true }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "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, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "flat-cache": { "version": "2.0.1", @@ -13667,6 +14509,29 @@ "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "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" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + } } }, "flatted": { @@ -13694,6 +14559,11 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -13774,12 +14644,12 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", - "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -13789,9 +14659,9 @@ "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fresh": { "version": "0.5.2", @@ -13799,9 +14669,9 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fromentries": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.1.tgz", - "integrity": "sha512-Xu2Qh8yqYuDhQGOhD5iJGninErSfI9A3FrriD3tjUgV5VbJFeH8vfgZ9HnC6jWN80QDVNQK5vmxRAmEAp7Mevw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true }, "fs-extra": { @@ -13821,9 +14691,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -13838,9 +14708,9 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -13891,6 +14761,15 @@ "pump": "^3.0.0" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -13900,33 +14779,33 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, "requires": { - "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", "dev": true, "requires": { - "ini": "^1.3.5" + "ini": "2.0.0" } }, "globals": { @@ -13957,9 +14836,9 @@ } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "growl": { @@ -13979,14 +14858,6 @@ "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "har-schema": { @@ -14011,15 +14882,28 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } }, "has-yarn": { "version": "2.1.0", @@ -14028,9 +14912,9 @@ "dev": true }, "hasha": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.1.tgz", - "integrity": "sha512-x15jnRSHTi3VmH+oHtVb9kgU/HuKOK8mjK8iCL3dPQXh4YJlUb9YSI8ZLiiqLAIvY2wuDIlZYZppy8vB2XISkQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, "requires": { "is-stream": "^2.0.0", @@ -14059,9 +14943,9 @@ "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==" }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-escaper": { @@ -14086,6 +14970,13 @@ "setprototypeof": "1.1.1", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } } }, "http-proxy-agent": { @@ -14096,21 +14987,6 @@ "@tootallnate/once": "1", "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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==" - } } }, "http-signature": { @@ -14124,9 +15000,9 @@ } }, "http-status": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.4.2.tgz", - "integrity": "sha512-mBnIohUwRw9NyXMEMMv8/GANnzEYUj0Y8d3uL01zDWFkxUjYyZ6rgCaAI2zZ1Wb34Oqtbx/nFZolPRDc8Xlm5A==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.5.0.tgz", + "integrity": "sha512-wcGvY31MpFNHIkUcXHHnvrE4IKYlpvitJw5P/1u892gMBAM46muQ+RH7UN1d+Ntnfx5apnOnVY6vcLmrWHOLwg==" }, "http-status-codes": { "version": "2.1.4", @@ -14140,21 +15016,6 @@ "requires": { "agent-base": "6", "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "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==" - } } }, "iconv-lite": { @@ -14166,15 +15027,15 @@ } }, "idtoken-verifier": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.1.0.tgz", - "integrity": "sha512-X0423UM4Rc5bFb39Ai0YHr35rcexlu4oakKdYzSGZxtoPy84P86hhAbzlpgbgomcLOFRgzgKRvhY7YjO5g8OPA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-2.2.2.tgz", + "integrity": "sha512-PFNivtWIUKFt0B53FOACLAM2PaejEwB/wh6fPqlWoLGMWP05JKGJyKyMv/uS9kduevEfRhHaSVdoLYUnQ0YmsA==", "requires": { - "base64-js": "^1.3.0", - "crypto-js": "^3.2.1", + "base64-js": "^1.5.1", + "crypto-js": "^4.1.1", "es6-promise": "^4.2.8", "jsbn": "^1.1.0", - "unfetch": "^4.1.0", + "unfetch": "^4.2.0", "url-join": "^4.0.1" }, "dependencies": { @@ -14202,9 +15063,9 @@ "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -14228,9 +15089,9 @@ "dev": true }, "inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz", + "integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==" }, "inflight": { "version": "1.0.6", @@ -14247,14 +15108,14 @@ "integrity": "sha1-J4QdcoZ920JCzWEtecEGM4gcang=" }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, "inquirer": { @@ -14277,19 +15138,23 @@ "through": "^2.3.6" }, "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -14313,12 +15178,32 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "supports-color": { @@ -14331,6 +15216,16 @@ } } }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -14352,15 +15247,26 @@ } }, "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } }, "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } }, "is-binary-path": { "version": "2.1.0", @@ -14371,16 +15277,24 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" }, "is-ci": { "version": "2.0.0", @@ -14391,6 +15305,15 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", @@ -14407,9 +15330,12 @@ } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-descriptor": { "version": "1.0.2", @@ -14439,39 +15365,36 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "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=" }, "is-generator-function": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", - "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==" + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } }, "is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, "requires": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" } }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "dev": true - }, "is-nan": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", @@ -14482,21 +15405,28 @@ } }, "is-negative-zero": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", - "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" }, "is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", + "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", "dev": true }, "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-6.0.0.tgz", + "integrity": "sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==" + }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-obj": { "version": "2.0.0", @@ -14505,15 +15435,15 @@ "dev": true }, "is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "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 }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-plain-object": { @@ -14531,47 +15461,50 @@ "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "requires": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "dev": true + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "requires": { - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" } }, "is-typed-array": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.3.tgz", - "integrity": "sha512-BSYUBOK/HJibQ30wWkWold5txYwMUXQct9YHAQJr8fSwvZoiglcqB0pd7vEN23+Tsi9IUEjztdOSzl4qLVYGTQ==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", + "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", "requires": { - "available-typed-arrays": "^1.0.0", - "es-abstract": "^1.17.4", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", "foreach": "^2.0.5", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" } }, "is-typedarray": { @@ -14579,6 +15512,14 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "requires": { + "call-bind": "^1.0.0" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -14619,9 +15560,9 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, "istanbul-lib-hook": { @@ -14679,6 +15620,20 @@ "which": "^2.0.1" } }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -14755,100 +15710,68 @@ } }, "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "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==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } } }, "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", + "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, - "iterate-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.1.tgz", - "integrity": "sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==", - "dev": true - }, - "iterate-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", - "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", - "dev": true, - "requires": { - "es-get-iterator": "^1.0.2", - "iterate-iterator": "^1.0.1" - } - }, "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" }, "joi": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.2.1.tgz", - "integrity": "sha512-YT3/4Ln+5YRpacdmfEfrrKh50/kkgX3LgBltjqnlMPIYiZ4hxXZuVJcxmsvxsdeHg9soZfE3qXxHC2tMpCCBOA==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.2.tgz", + "integrity": "sha512-Lm56PP+n0+Z2A2rfRvsfWVDXGEWjXxatPopkQ8qQ5mxCEhwHG+Ettgg5o98FFaxilOxozoa14cFhrE/hOzh/Nw==", "requires": { - "@hapi/address": "^4.1.0", - "@hapi/formula": "^2.0.0", "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" } }, "js-beautify": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.13.0.tgz", - "integrity": "sha512-/Tbp1OVzZjbwzwJQFIlYLm9eWQ+3aYbBXLSaqb1mEJzhcQAfrqMMQYtjb6io+U6KpD0ID4F+Id3/xcjH3l/sqA==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.0.tgz", + "integrity": "sha512-yuck9KirNSCAwyNJbqW+BxJqJ0NLJ4PwBUzQQACl5O3qHMBXVkXb/rD0ilh/Lat/tn88zSZ+CAHOlk0DsY7GuQ==", "dev": true, "requires": { "config-chain": "^1.1.12", "editorconfig": "^0.15.3", "glob": "^7.1.3", - "mkdirp": "^1.0.4", "nopt": "^5.0.0" }, "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } }, "nopt": { "version": "5.0.0", @@ -14872,9 +15795,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -14924,9 +15847,9 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "requires": { "minimist": "^1.2.5" } @@ -14955,18 +15878,6 @@ "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^5.6.0" - }, - "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==" - } } }, "jsprim": { @@ -14991,9 +15902,9 @@ } }, "just-extend": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", - "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "jwa": { @@ -15024,37 +15935,17 @@ }, "dependencies": { "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "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": "^1.14.0" } }, "follow-redirects": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", - "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", + "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==" } } }, @@ -15082,13 +15973,6 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { "is-buffer": "^1.1.5" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - } } }, "koalas": { @@ -15167,22 +16051,29 @@ "parse-json": "^2.2.0", "pify": "^2.0.0", "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "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, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.clonedeep": { "version": "4.5.0", @@ -15255,19 +16146,18 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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": "^4.1.0", @@ -15318,61 +16208,18 @@ "success-symbol": "^0.1.0", "time-stamp": "^1.0.1", "warning-symbol": "^0.1.0" - }, - "dependencies": { - "ansi-colors": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz", - "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=", - "requires": { - "ansi-bgblack": "^0.1.1", - "ansi-bgblue": "^0.1.1", - "ansi-bgcyan": "^0.1.1", - "ansi-bggreen": "^0.1.1", - "ansi-bgmagenta": "^0.1.1", - "ansi-bgred": "^0.1.1", - "ansi-bgwhite": "^0.1.1", - "ansi-bgyellow": "^0.1.1", - "ansi-black": "^0.1.1", - "ansi-blue": "^0.1.1", - "ansi-bold": "^0.1.1", - "ansi-cyan": "^0.1.1", - "ansi-dim": "^0.1.1", - "ansi-gray": "^0.1.1", - "ansi-green": "^0.1.1", - "ansi-grey": "^0.1.1", - "ansi-hidden": "^0.1.1", - "ansi-inverse": "^0.1.1", - "ansi-italic": "^0.1.1", - "ansi-magenta": "^0.1.1", - "ansi-red": "^0.1.1", - "ansi-reset": "^0.1.1", - "ansi-strikethrough": "^0.1.1", - "ansi-underline": "^0.1.1", - "ansi-white": "^0.1.1", - "ansi-yellow": "^0.1.1", - "lazy-cache": "^2.0.1" - } - } } }, "logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", + "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", "requires": { "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", "fecha": "^4.2.0", "ms": "^2.1.1", + "safe-stable-stringify": "^1.1.0", "triple-beam": "^1.3.0" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "long": { @@ -15429,9 +16276,9 @@ } }, "luxon": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz", - "integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==" + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", + "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==" }, "make-dir": { "version": "3.1.0", @@ -15464,19 +16311,27 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "memoizee": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", - "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "dev": true, "requires": { - "d": "1", - "es5-ext": "^0.10.45", - "es6-weak-map": "^2.0.2", + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", - "is-promise": "^2.1", - "lru-queue": "0.1", - "next-tick": "1", - "timers-ext": "^0.1.5" + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "dependencies": { + "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 + } } }, "merge-descriptors": { @@ -15500,16 +16355,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "requires": { - "mime-db": "1.44.0" + "mime-db": "1.50.0" } }, "mimic-fn": { @@ -15561,45 +16416,65 @@ } }, "mocha": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.1.3.tgz", - "integrity": "sha512-ZbaYib4hT4PpF4bdSO2DohooKXIn4lDeiYqB+vTmCdr6l2woW0b6H3pf5x4sM5nwQMru9RvjjHYWVGltR50ZBw==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "dev": true, "requires": { + "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.2", - "debug": "4.1.1", - "diff": "4.0.2", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", + "js-yaml": "4.0.0", "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "object.assign": "4.1.0", - "promise.allsettled": "1.0.2", - "serialize-javascript": "4.0.0", - "strip-json-comments": "3.0.1", - "supports-color": "7.1.0", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.0", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.1" + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { - "debug": { + "ansi-colors": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "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 + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "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==", + "dev": true + } } }, "escape-string-regexp": { @@ -15608,14 +16483,18 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "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==", + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "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" } }, "has-flag": { @@ -15624,73 +16503,19 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "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, - "requires": { - "p-locate": "^5.0.0" - } - }, - "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 - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "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==", + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, "requires": { - "p-limit": "^3.0.2" + "argparse": "^2.0.1" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "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 - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15721,9 +16546,9 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "murmur-hash-js": { "version": "1.0.0", @@ -15732,9 +16557,9 @@ "dev": true }, "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "mv": { "version": "2.1.1", @@ -15745,38 +16570,20 @@ "mkdirp": "~0.5.1", "ncp": "~2.0.0", "rimraf": "~2.4.0" - }, - "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.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "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.1" - } - } } }, "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", "optional": true }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -15820,9 +16627,9 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "nise": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", - "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", @@ -15884,6 +16691,12 @@ "process-on-spawn": "^1.0.0" } }, + "node-releases": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "dev": true + }, "node-schedule": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.0.0.tgz", @@ -15895,9 +16708,9 @@ } }, "nodemon": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.4.tgz", - "integrity": "sha512-Ltced+hIfTmaS28Zjv1BM552oQ3dbwPqI4+zI0SLgq+wpJhSyqgYude/aZa/3i31VCQWMfXJVxvu86abcam3uQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.14.tgz", + "integrity": "sha512-frcpDx+PviKEQRSYzwhckuO2zoHcBYLHI754RE9z5h1RGtrngerc04mLpQQCPWBkH/2ObrX7We9YiwVSYZpFJQ==", "dev": true, "requires": { "chokidar": "^3.2.2", @@ -15908,30 +16721,18 @@ "semver": "^5.7.1", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^4.0.0" + "undefsafe": "^2.0.3", + "update-notifier": "^5.1.0" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } - }, - "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 - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true } } }, @@ -15954,14 +16755,6 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, "normalize-path": { @@ -15971,9 +16764,9 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "nyc": { @@ -16011,17 +16804,28 @@ "yargs": "^15.0.2" }, "dependencies": { + "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 + }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, - "cliui": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", @@ -16047,6 +16851,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -16057,6 +16867,26 @@ "path-exists": "^4.0.0" } }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -16084,18 +16914,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "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 - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -16111,13 +16929,24 @@ "glob": "^7.1.3" } }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "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": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "wrap-ansi": { @@ -16131,6 +16960,12 @@ "strip-ansi": "^6.0.0" } }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", @@ -16226,9 +17061,9 @@ } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" }, "object-keys": { "version": "1.1.1", @@ -16244,70 +17079,47 @@ } }, "object.assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", - "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.0", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } } }, "object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "object.fromentries": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", - "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "on-finished": { @@ -16367,21 +17179,21 @@ "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "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, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" } }, "p-map": { @@ -16394,9 +17206,9 @@ } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "package-hash": { @@ -16459,9 +17271,9 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "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 }, "path-is-absolute": { @@ -16475,9 +17287,9 @@ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { @@ -16495,9 +17307,9 @@ } }, "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "performance-now": { @@ -16506,30 +17318,30 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pg": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.4.0.tgz", - "integrity": "sha512-01LcNrAf+mBI46c78mE86I5o5KkOM942lLiSBdiCfgHTR+oUNIjh1fKClWeoPNHJz2oXe/VUSqtk1vwAQYwWEg==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz", + "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.4.0", - "pg-pool": "^3.2.1", - "pg-protocol": "^1.3.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.4.1", + "pg-protocol": "^1.5.0", "pg-types": "^2.1.0", "pgpass": "1.x" } }, "pg-connection-string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", - "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" }, "pg-hstore": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.3.tgz", - "integrity": "sha512-qpeTpdkguFgfdoidtfeTho1Q1zPVPbtMHgs8eQ+Aan05iLmIs3Z3oo5DOZRclPGoQ4i68I1kCtQSJSa7i0ZVYg==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.4.tgz", + "integrity": "sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA==", "requires": { - "underscore": "^1.7.0" + "underscore": "^1.13.1" } }, "pg-int8": { @@ -16538,15 +17350,15 @@ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, "pg-pool": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", - "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz", + "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==", "requires": {} }, "pg-protocol": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.3.0.tgz", - "integrity": "sha512-64/bYByMrhWULUaCd+6/72c9PMWhiVFs3EVxl9Ct6a3v/U8+rKgqP2w+kKg/BIGgMJyB+Bk/eNivT32Al+Jghw==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" }, "pg-types": { "version": "2.2.0", @@ -16561,17 +17373,23 @@ } }, "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", "requires": { - "split": "^1.0.0" + "split2": "^3.1.1" } }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { @@ -16640,12 +17458,6 @@ "p-limit": "^2.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -16656,12 +17468,24 @@ "json-parse-better-errors": "^1.0.1" } }, + "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 + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", @@ -16682,12 +17506,51 @@ } }, "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "find-up": "^2.1.0" + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } } }, "pointer-symbol": { @@ -16753,25 +17616,27 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, - "promise.allsettled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", - "integrity": "sha512-UpcYW5S1RaNKT6pd+s9jp9K9rlQge1UXKskec0j6Mmuq7UJCvlS2J2/s/yuPN8ehftf9HXMxWlKiPbGGUzpoRg==", - "dev": true, - "requires": { - "array.prototype.map": "^1.0.1", - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "iterate-value": "^1.0.0" - } - }, "prompt-actions": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/prompt-actions/-/prompt-actions-3.0.2.tgz", "integrity": "sha512-dhz2Fl7vK+LPpmnQ/S/eSut4BnH4NZDLyddHKi5uTU/2PDn3grEMGkgsll16V5RpVUh/yxdiam0xsM0RD4xvtg==", "requires": { "debug": "^2.6.8" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "prompt-base": { @@ -16797,11 +17662,6 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -16847,11 +17707,6 @@ "isobject": "^3.0.1" } }, - "is-number": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-6.0.0.tgz", - "integrity": "sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==" - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -16902,11 +17757,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -16928,17 +17778,17 @@ "dev": true }, "protocol-buffers-schema": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz", - "integrity": "sha512-YVCvdhxWNDP8/nJDyXLuM+UFsuPk4+1PB7WGPVDzm3HTHbzFLxQYeW2iZpS4mmnXrQJGBzt230t/BbEb7PrQaw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", "dev": true }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -16978,24 +17828,33 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dev": true, "requires": { "escape-goat": "^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==" + "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" + } }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, + "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 + }, "r7insight_node": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/r7insight_node/-/r7insight_node-1.8.4.tgz", @@ -17068,6 +17927,12 @@ "strip-json-comments": "~2.0.1" }, "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -17101,22 +17966,77 @@ "requires": { "find-up": "^2.0.0", "read-pkg": "^2.0.0" + }, + "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": { + "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" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "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" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "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 + } } }, "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==", + "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": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "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" } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -17133,32 +18053,18 @@ "string-width": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "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" + } }, - "is-fullwidth-code-point": { + "ms": { "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=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "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=", - "requires": { - "ansi-regex": "^3.0.0" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -17178,11 +18084,6 @@ "window-size": "^1.1.0" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -17190,11 +18091,6 @@ "requires": { "kind-of": "^3.0.2" } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" } } }, @@ -17212,9 +18108,9 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" }, "registry-auth-token": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", - "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { "rc": "^1.2.8" @@ -17300,11 +18196,12 @@ "dev": true }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, @@ -17331,6 +18228,11 @@ "signal-exit": "^3.0.2" } }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, "retry-as-promised": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", @@ -17348,11 +18250,12 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, "requires": { - "glob": "^7.1.3" + "glob": "^6.0.1" } }, "run-async": { @@ -17361,15 +18264,18 @@ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true + "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, + "requires": { + "queue-microtask": "^1.2.2" + } }, "rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "requires": { "tslib": "^1.9.0" } @@ -17385,6 +18291,11 @@ "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", "optional": true }, + "safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -17396,14 +18307,14 @@ "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, "secure-json-parse": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.1.0.tgz", - "integrity": "sha512-GckO+MS/wT4UogDyoI/H/S1L0MCcKS1XX/vp48wfmU7Nw4woBmb8mIpu4zPBQjKlRT88/bt9xdoV4111jPpNJA==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.4.0.tgz", + "integrity": "sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==" }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-diff": { "version": "3.1.1", @@ -17442,6 +18353,21 @@ "statuses": "~1.5.0" }, "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=" + } + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -17450,14 +18376,14 @@ } }, "sequelize": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.3.5.tgz", - "integrity": "sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.7.0.tgz", + "integrity": "sha512-OVw3psUggqQT9kYg5Z9fja/BMdBxX/Ua3Bwx2yif5g6QuYEE4UfWq5jW6LmbacGwgK6bgZs05Q2zCkJZCDFrSA==", "requires": { "debug": "^4.1.1", "dottie": "^2.0.0", - "inflection": "1.12.0", - "lodash": "^4.17.15", + "inflection": "1.13.1", + "lodash": "^4.17.20", "moment": "^2.26.0", "moment-timezone": "^0.5.31", "retry-as-promised": "^3.2.0", @@ -17465,22 +18391,30 @@ "sequelize-pool": "^6.0.0", "toposort-class": "^1.0.1", "uuid": "^8.1.0", - "validator": "^10.11.0", + "validator": "^13.6.0", "wkx": "^0.5.0" }, "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "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": { - "ms": "2.1.2" + "yallist": "^4.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -17497,6 +18431,151 @@ "resolve": "^1.5.0", "umzug": "^2.3.0", "yargs": "^13.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "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 + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "sequelize-pool": { @@ -17505,9 +18584,9 @@ "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==" }, "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -17531,9 +18610,9 @@ "dev": true }, "set-getter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", - "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", + "integrity": "sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==", "requires": { "to-object-path": "^0.3.0" } @@ -17589,13 +18668,6 @@ "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" - }, - "dependencies": { - "object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - } } }, "sigmund": { @@ -17605,9 +18677,9 @@ "dev": true }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "simple-lru-cache": { "version": "0.0.2", @@ -17621,30 +18693,28 @@ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", "requires": { "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - } } }, "sinon": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.0.tgz", - "integrity": "sha512-eSNXz1XMcGEMHw08NJXSyTHIu6qTCOiN8x9ODACmZpNQpr0aXTBXBnI4xTzQzR+TEpOmLiKowGf9flCuKIzsbw==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", "dev": true, "requires": { "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/formatio": "^5.0.1", - "@sinonjs/samsam": "^5.2.0", + "@sinonjs/samsam": "^5.3.1", "diff": "^4.0.2", "nise": "^4.0.4", "supports-color": "^7.1.0" }, "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -17670,13 +18740,6 @@ "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "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=" - } } }, "sorted-array-functions": { @@ -17685,9 +18748,9 @@ "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==" }, "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "spawn-wrap": { @@ -17704,6 +18767,20 @@ "which": "^2.0.1" }, "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -17751,17 +18828,29 @@ } }, "spdx-license-ids": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", - "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "requires": { - "through": "2" + "readable-stream": "^3.0.0" + }, + "dependencies": { + "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" + } + } } }, "sprintf-js": { @@ -17854,11 +18943,6 @@ } } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -17905,77 +18989,52 @@ "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" }, "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==", + "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.2.0" - }, - "dependencies": { - "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==" - } + "safe-buffer": "~5.1.0" } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - } + "ansi-regex": "^3.0.0" } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, "strip-color": { @@ -17989,9 +19048,9 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, "stripe": { - "version": "8.168.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.168.0.tgz", - "integrity": "sha512-MQXTarijIOagtLajGe1zBFc9KMbB7jIoFv/kr1WsDPJO/S+/hhZjsXCgBkNvnlwK7Yl0VUn+YrgXl9/9wU6WCw==", + "version": "8.183.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-8.183.0.tgz", + "integrity": "sha512-QcM3nimH1CuP49VPPRt36Wgfu4QoS+Wm0eyGMis7Ej+seWFKqMffMdx7TE2gn8dVsJIOA1kDuIbAQGqpZHozGA==", "requires": { "@types/node": ">=8.1.0", "qs": "^6.6.0" @@ -18020,28 +19079,51 @@ "semver": "^7.3.2" }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "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": { - "ms": "2.1.2" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "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" } }, "mime": { - "version": "2.4.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", - "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" + "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==" + "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" + } }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + "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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -18064,16 +19146,16 @@ "string-width": "^3.0.0" }, "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, - "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=" - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -18083,6 +19165,14 @@ "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } } } }, @@ -18109,6 +19199,14 @@ "follow-redirects": "0.0.7" } }, + "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" + } + }, "follow-redirects": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz", @@ -18117,15 +19215,14 @@ "debug": "^2.2.0", "stream-consume": "^0.1.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, - "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", - "dev": true - }, "terminal-paginator": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/terminal-paginator/-/terminal-paginator-2.0.2.tgz", @@ -18134,6 +19231,21 @@ "debug": "^2.6.6", "extend-shallow": "^2.0.1", "log-utils": "^0.2.1" + }, + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, "test-exclude": { @@ -18145,6 +19257,22 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + } } }, "text-hex": { @@ -18212,6 +19340,14 @@ "dev": true, "requires": { "is-number": "^7.0.0" + }, + "dependencies": { + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + } } }, "toggle-array": { @@ -18271,9 +19407,9 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "tunnel-agent": { "version": "0.6.0", @@ -18332,9 +19468,9 @@ } }, "uglify-js": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.0.tgz", - "integrity": "sha512-R/tiGB1ZXp2BC+TkRGLwj8xUZgdfT2f4UZEgX6aVjJ5uttPrr4fYmwTWDGqVnBCLbOXRMY6nr/BTbwCtVfps0g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", "dev": true, "optional": true }, @@ -18347,19 +19483,27 @@ "bluebird": "^3.7.2" } }, - "undefsafe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", - "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", - "dev": true, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", "requires": { - "debug": "^2.2.0" + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" } }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, "underscore": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz", - "integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", + "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" }, "unfetch": { "version": "4.2.0", @@ -18393,40 +19537,40 @@ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "update-notifier": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", - "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", + "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", "dev": true, "requires": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", + "boxen": "^5.0.0", + "chalk": "^4.1.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", + "is-installed-globally": "^0.4.0", + "is-npm": "^5.0.0", "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", + "latest-version": "^5.1.0", + "pupa": "^2.1.1", + "semver": "^7.3.4", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "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": "^4.1.0", @@ -18454,6 +19598,24 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "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==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -18462,17 +19624,28 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "requires": { "punycode": "^2.1.0" } }, + "urijs": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.7.tgz", + "integrity": "sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==" + }, "url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", @@ -18504,9 +19677,9 @@ } }, "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", + "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -18527,14 +19700,14 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -18547,9 +19720,9 @@ } }, "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz", + "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==" }, "vary": { "version": "1.1.2", @@ -18564,6 +19737,13 @@ "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" + }, + "dependencies": { + "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=" + } } }, "warning-symbol": { @@ -18579,6 +19759,18 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -18586,16 +19778,16 @@ "dev": true }, "which-typed-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.2.tgz", - "integrity": "sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", + "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", "requires": { - "available-typed-arrays": "^1.0.2", - "es-abstract": "^1.17.5", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.5", "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.7" } }, "wide-align": { @@ -18605,50 +19797,51 @@ "dev": true, "requires": { "string-width": "^1.0.2 || 2" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "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=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "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": "^3.0.0" + "ansi-regex": "^5.0.1" } } } }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, "winchan": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/winchan/-/winchan-0.2.2.tgz", @@ -18687,6 +19880,18 @@ "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.4.0" + }, + "dependencies": { + "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" + } + } } }, "winston-transport": { @@ -18696,30 +19901,6 @@ "requires": { "readable-stream": "^2.3.7", "triple-beam": "^1.2.0" - }, - "dependencies": { - "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.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" - } - }, - "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.0" - } - } } }, "wkx": { @@ -18742,43 +19923,76 @@ "dev": true }, "workerpool": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", - "integrity": "sha512-fU2OcNA/GVAJLLyKUoHkAgIhKb0JoCpSjLC/G2vYKxUjVmQwGbRVeoPJ1a8U4pnVofz4AQV5Y/NEw8oKqxEBtA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "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 + }, + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 }, "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=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "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": "^5.0.1" } } } @@ -18843,9 +20057,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { @@ -18854,210 +20068,77 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "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 }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, "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 - }, - "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "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": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "ansi-regex": "^5.0.1" } } } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", - "integrity": "sha512-qZV14lK9MWsGCmcr7u5oXGH0dbGqZAIxTDrWXZDo5zUr6b6iUmelNKO6x6R1dQT24AH3LgRxJpr8meWy2unolA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "decamelize": "^1.2.0", - "flat": "^4.1.0", - "is-plain-obj": "^1.1.0", - "yargs": "^14.2.3" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "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 - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - } - }, - "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" } + }, + "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 } } } diff --git a/package.json b/package.json index 0841db9f..3e378af5 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "start": "node app.js", "dev": "nodemon app.js", + "dev:debug": "nodemon --inspect app.js", "lint": "standard", "lint:fix": "standard --fix", "init-db": "node src/init-db.js", @@ -16,6 +17,7 @@ "index:jobs": "node scripts/es/reIndexJobs.js", "index:job-candidates": "node scripts/es/reIndexJobCandidates.js", "index:resource-bookings": "node scripts/es/reIndexResourceBookings.js", + "index:user-meeting-settings": "node scripts/es/reIndexUserMeetingSettings.js", "index:roles": "node scripts/es/reIndexRoles.js", "data:export": "node scripts/data/exportData.js", "data:import": "node scripts/data/importData.js", @@ -29,8 +31,7 @@ "local:init": "npm run local:reset && npm run data:import -- --force", "local:reset": "npm run delete-index -- --force || true && npm run create-index -- --force && npm run init-db force", "cov": "nyc --reporter=html --reporter=text npm run test", - "demo-payment-scheduler": "node scripts/demo-payment-scheduler/index.js && npm run index:all -- --force", - "demo-payment": "node scripts/demo-payment", + "demo-email-notifications": "node scripts/demo-email-notifications", "migrate:backup-withdrawn": "node scripts/withdrawn-migration/backup.js", "migrate:migration-withdrawn": "node scripts/withdrawn-migration/migration.js", "migrate:restore-withdrawn": "node scripts/withdrawn-migration/restore.js", @@ -45,9 +46,10 @@ "author": "", "license": "ISC", "dependencies": { - "@elastic/elasticsearch": "^7.9.1", + "@elastic/elasticsearch": "7.9.1", "@joi/date": "^2.0.1", "@topcoder-platform/topcoder-bus-api-wrapper": "github:topcoder-platform/tc-bus-api-wrapper", + "async-mutex": "^0.3.2", "aws-sdk": "^2.787.0", "bottleneck": "^2.19.5", "config": "^3.3.2", @@ -60,6 +62,7 @@ "http-status": "^1.4.2", "http-status-codes": "^2.1.4", "joi": "^17.2.1", + "jsonwebtoken": "^8.5.1", "lodash": "^4.17.20", "moment": "^2.29.1", "moment-timezone": "^0.5.33", @@ -67,11 +70,13 @@ "pg": "^8.4.0", "pg-hstore": "^2.3.3", "prompt-confirm": "^2.0.4", + "retry": "^0.13.1", "rewire": "^5.0.0", "sequelize": "^6.3.5", "stripe": "^8.168.0", "superagent": "^6.1.0", "tc-core-library-js": "github:appirio-tech/tc-core-library-js#v2.6", + "urijs": "^1.19.7", "util": "^0.12.3", "uuid": "^8.3.1", "winston": "^3.3.3" diff --git a/scripts/data/exportData.js b/scripts/data/exportData.js index cb61e582..e4360171 100644 --- a/scripts/data/exportData.js +++ b/scripts/data/exportData.js @@ -28,7 +28,7 @@ const resourceBookingModelOpts = { const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: are you sure you want to export all data in the database to a json file with the path ${filePath}? This will overwrite the file.` -const dataModels = ['Job', jobCandidateModelOpts, resourceBookingModelOpts, 'Role'] +const dataModels = ['Job', jobCandidateModelOpts, resourceBookingModelOpts, 'Role', 'UserMeetingSettings'] async function exportData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/data/importData.js b/scripts/data/importData.js index a0aeeb64..4aa47457 100644 --- a/scripts/data/importData.js +++ b/scripts/data/importData.js @@ -28,7 +28,7 @@ const resourceBookingModelOpts = { const filePath = helper.getParamFromCliArgs() || config.DEFAULT_DATA_FILE_PATH const userPrompt = `WARNING: this would remove existing data. Are you sure you want to import data from a json file with the path ${filePath}?` -const dataModels = ['Job', jobCandidateModelOpts, resourceBookingModelOpts, 'Role'] +const dataModels = ['Job', jobCandidateModelOpts, resourceBookingModelOpts, 'Role', 'UserMeetingSettings'] async function importData () { await helper.promptUser(userPrompt, async () => { diff --git a/scripts/demo-email-notifications/README.md b/scripts/demo-email-notifications/README.md index e55e275d..be30ce2a 100644 --- a/scripts/demo-email-notifications/README.md +++ b/scripts/demo-email-notifications/README.md @@ -17,6 +17,28 @@ This script does 2 things: CRON_UPCOMING_RESOURCE_BOOKING=0 */1 * * * * INTERVIEW_COMING_UP_MATCH_WINDOW=PT1M INTERVIEW_COMPLETED_MATCH_WINDOW=PT1M + TAAS_NOTIFICATION_JOB_CANDIDATE_RESUME_VIEWED_SENDGRID_TEMPLATE_ID=1 + TAAS_NOTIFICATION_CANDIDATES_AVAILABLE_FOR_REVIEW_SENDGRID_TEMPLATE_ID=2 + TAAS_NOTIFICATION_INTERVIEW_COMING_UP_HOST_SENDGRID_TEMPLATE_ID=3 + TAAS_NOTIFICATION_INTERVIEW_COMING_UP_GUEST_SENDGRID_TEMPLATE_ID=4 + TAAS_NOTIFICATION_INTERVIEW_AWAITS_RESOLUTION_SENDGRID_TEMPLATE_ID=5 + TAAS_NOTIFICATION_POST_INTERVIEW_ACTION_REQUIRED_SENDGRID_TEMPLATE_ID=6 + TAAS_NOTIFICATION_RESOURCE_BOOKING_EXPIRATION_SENDGRID_TEMPLATE_ID=7 + TAAS_NOTIFICATION_TEAM_CREATED_SENDGRID_TEMPLATE_ID=8 + TAAS_NOTIFICATION_JOB_CREATED_SENDGRID_TEMPLATE_ID=9 + TAAS_NOTIFICATION_INTERVIEWS_OVERLAPPING_SENDGRID_TEMPLATE_ID=10 + TAAS_NOTIFICATION_JOB_CANDIDATE_SELECTED_SENDGRID_TEMPLATE_ID=11 + TAAS_NOTIFICATION_RESOURCE_BOOKING_PLACED_SENDGRID_TEMPLATE_ID=12 + TAAS_NOTIFICATION_INTERVIEW_SCHEDULE_REMINDER_SENDGRID_TEMPLATE_ID=13 + TAAS_NOTIFICATION_INTERVIEW_EXPIRED_GUEST_SENDGRID_TEMPLATE_ID=14 + TAAS_NOTIFICATION_INTERVIEW_EXPIRED_HOST_SENDGRID_TEMPLATE_ID=15 + TAAS_NOTIFICATION_INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID=16 + TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_HOST_SENDGRID_TEMPLATE_ID=17 + TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_GUEST_SENDGRID_TEMPLATE_ID=18 + TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_HOST_SENDGRID_TEMPLATE_ID=19 + TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_GUEST_SENDGRID_TEMPLATE_ID=20 + TAAS_NOTIFICATION_INTERVIEW_CANCELLED_HOST_SENDGRID_TEMPLATE_ID=21 + TAAS_NOTIFICATION_INTERVIEW_CANCELLED_GUEST_SENDGRID_TEMPLATE_ID=22 ``` 2. Config `SLACK_WEBHOOK_URL` env, if you want to send slack notifications diff --git a/scripts/demo-email-notifications/index.js b/scripts/demo-email-notifications/index.js index 87ee16b8..8088551a 100644 --- a/scripts/demo-email-notifications/index.js +++ b/scripts/demo-email-notifications/index.js @@ -16,7 +16,30 @@ const localLogger = { info: message => logger.info({ component: 'render email content', context: 'test', message }) } -const template = handlebars.compile(fs.readFileSync('./data/notifications-email-template.html', 'utf8')) +const templateFileMap = { + [config.TAAS_NOTIFICATION_JOB_CANDIDATE_RESUME_VIEWED_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.job-candidate-resume-viewed.html', 'utf8')), + [config.TAAS_NOTIFICATION_CANDIDATES_AVAILABLE_FOR_REVIEW_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.candidates-available-for-review.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_COMING_UP_HOST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-coming-up-host.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_COMING_UP_GUEST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-coming-up-guest.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_AWAITS_RESOLUTION_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-awaits-resolution.html', 'utf8')), + [config.TAAS_NOTIFICATION_POST_INTERVIEW_ACTION_REQUIRED_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.post-interview-action-required.html', 'utf8')), + [config.TAAS_NOTIFICATION_RESOURCE_BOOKING_EXPIRATION_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.resource-booking-expiration.html', 'utf8')), + [config.TAAS_NOTIFICATION_TEAM_CREATED_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.team-created.html', 'utf8')), + [config.TAAS_NOTIFICATION_JOB_CREATED_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.job-created.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEWS_OVERLAPPING_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interviews-overlapping.html', 'utf8')), + [config.TAAS_NOTIFICATION_JOB_CANDIDATE_SELECTED_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.job-candidate-selected.html', 'utf8')), + [config.TAAS_NOTIFICATION_RESOURCE_BOOKING_PLACED_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.resource-booking-placed.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_SCHEDULE_REMINDER_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-schedule-reminder.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_EXPIRED_GUEST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-expired-guest.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_EXPIRED_HOST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-expired-host.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_INVITATION_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-invitation.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_HOST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-link-for-host.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_LINK_FOR_GUEST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-link-for-guest.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_HOST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-rescheduled-host.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_RESCHEDULED_GUEST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-rescheduled-guest.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_CANCELLED_HOST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-cancelled-host.html', 'utf8')), + [config.TAAS_NOTIFICATION_INTERVIEW_CANCELLED_GUEST_SENDGRID_TEMPLATE_ID]: handlebars.compile(fs.readFileSync('./data/notification-email-templates/taas.notification.interview-cancelled-guest.html', 'utf8')) +} /** * Reset notification records @@ -26,7 +49,7 @@ async function resetNotificationRecords () { localLogger.info('reset coming up interview records') const interview = await Interview.findById('976d23a9-5710-453f-99d9-f57a588bb610') const startTimestamp = moment().add(moment.duration(config.INTERVIEW_COMING_UP_REMIND_TIME[0])).add(config.INTERVIEW_COMING_UP_MATCH_WINDOW).toDate() - await interview.update({ startTimestamp, duration: 30, status: Interviews.Status.Scheduled, guestNames: ['test1', 'test2'], hostName: 'hostName' }) + await interview.update({ startTimestamp, duration: 30, status: Interviews.Status.Scheduled, guestNames: ['test1', 'test2'], hostName: 'hostName', guestTimezone: 'Europe/London' }) // reset completed interview records localLogger.info('reset completed interview records') @@ -38,6 +61,8 @@ async function resetNotificationRecords () { await completedInterview.update({ startTimestamp: completedStartTimestamp, duration, endTimeStamp: completedEndTimestamp, status: Interviews.Status.Scheduled, guestNames: ['guest1', 'guest2'], hostName: 'hostName' }) const completedInterview2 = await Interview.findById('3144fa65-ea1a-4bec-81b0-7cb1c8845826') await completedInterview2.update({ startTimestamp: completedStartTimestamp, duration, endTimeStamp: completedEndTimestamp, status: Interviews.Status.Scheduled, guestNames: ['guest1', 'guest2'], hostName: 'hostName' }) + const jobCandidateForInterview = await JobCandidate.findById('a4ea7bcf-5b99-4381-b99c-a9bd05d83a36') + await jobCandidateForInterview.update({ status: 'interview' }) // reset post interview candidate action reminder records localLogger.info('reset post interview candidate action reminder records') @@ -48,6 +73,13 @@ async function resetNotificationRecords () { const c2InterviewR2 = await Interview.findById('b1f7ba76-640f-47e2-9463-59e51b51ec60') await c2InterviewR2.update({ status: 'Scheduled', startTimestamp: moment().subtract(moment.duration(config.POST_INTERVIEW_ACTION_MATCH_WINDOW)).subtract(30, 'm').toDate(), duration, endTimeStamp: completedEndTimestamp, guestNames: ['guest1', 'guest2'], hostName: 'hostName' }) + const interviewForReminder = await Interview.findById('a23e1bf2-1084-4cfe-a0d8-d83bc6fec655') + // update hostUserId to test user phash_manager + await interviewForReminder.update({ createdAt: moment().subtract(moment.duration(config.INTERVIEW_REMINDER_DAY_AFTER)).toDate(), hostUserId: '57646ff9-1cd3-4d3c-88ba-eb09a395366c' }) + + const interviewExpired = await Interview.findById('505db942-79fe-4b6f-974c-b359e1b61967') + await interviewExpired.update({ expireTimestamp: moment().subtract(moment.duration(1, 'days')).toDate(), hostUserId: '57646ff9-1cd3-4d3c-88ba-eb09a395366c' }) + // reset upcoming resource booking expiration records localLogger.info('reset upcoming resource booking expiration records') const resourceBooking = await ResourceBooking.findById('62c3f0c9-2bf0-4f24-8647-2c802a39cbcb') @@ -71,8 +103,8 @@ async function initConsumer () { } if (message.payload.notifications) { _.forEach(_.filter(message.payload.notifications, ['serviceId', 'email']), (notification) => { - const email = template(notification.details.data) - fs.writeFileSync(`./out/${notification.details.data.subject}-${Date.now()}.html`, email) + const email = templateFileMap[notification.details.sendgridTemplateId](notification.details.data) + fs.writeFileSync(`./out/${notification.details.data.subject.replace(/[^a-z0-9 ]/gi, '_')}-${Date.now()}.html`, email) }) for (const notification of _.filter(message.payload.notifications, ['serviceId', 'slack'])) { if (process.env.SLACK_WEBHOOK_URL) { diff --git a/scripts/es/createIndex.js b/scripts/es/createIndex.js index 269cd5a4..307cc7c0 100644 --- a/scripts/es/createIndex.js +++ b/scripts/es/createIndex.js @@ -9,7 +9,8 @@ const indices = [ config.get('esConfig.ES_INDEX_JOB'), config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), - config.get('esConfig.ES_INDEX_ROLE') + config.get('esConfig.ES_INDEX_ROLE'), + config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS') ] const userPrompt = `WARNING: Are you sure want to create the following elasticsearch indices: ${indices}?` diff --git a/scripts/es/deleteIndex.js b/scripts/es/deleteIndex.js index 724d3556..324d6421 100644 --- a/scripts/es/deleteIndex.js +++ b/scripts/es/deleteIndex.js @@ -9,7 +9,8 @@ const indices = [ config.get('esConfig.ES_INDEX_JOB'), config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), - config.get('esConfig.ES_INDEX_ROLE') + config.get('esConfig.ES_INDEX_ROLE'), + config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS') ] const userPrompt = `WARNING: this would remove existent data! Are you sure want to delete the following eleasticsearch indices: ${indices}?` diff --git a/scripts/es/reIndexAll.js b/scripts/es/reIndexAll.js index 0367be11..73e17e6d 100644 --- a/scripts/es/reIndexAll.js +++ b/scripts/es/reIndexAll.js @@ -35,6 +35,7 @@ async function indexAll () { await helper.indexBulkDataToES(jobCandidateModelOpts, config.get('esConfig.ES_INDEX_JOB_CANDIDATE'), logger) await helper.indexBulkDataToES(resourceBookingModelOpts, config.get('esConfig.ES_INDEX_RESOURCE_BOOKING'), logger) await helper.indexBulkDataToES('Role', config.get('esConfig.ES_INDEX_ROLE'), logger) + await helper.indexBulkDataToES('UserMeetingSettings', config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS'), logger) process.exit(0) } catch (err) { logger.logFullError(err, { component: 'indexAll' }) diff --git a/scripts/es/reIndexUserMeetingSettings.js b/scripts/es/reIndexUserMeetingSettings.js new file mode 100644 index 00000000..057e32f2 --- /dev/null +++ b/scripts/es/reIndexUserMeetingSettings.js @@ -0,0 +1,41 @@ +/** + * Reindex UserMeetingSettings data in Elasticsearch using data from database + */ +const config = require('config') +const logger = require('../../src/common/logger') +const helper = require('../../src/common/helper') + +const userId = helper.getParamFromCliArgs() +const index = config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS') +const reIndexAllUserMeetingSettingsPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the index ${index}?` +const reIndexUserMeetingSettingPrompt = `WARNING: this would remove existent data! Are you sure you want to reindex the document with id ${userId} in index ${index}?` + +const userMeetingSettingModelOpts = { + modelName: 'UserMeetingSettings' +} + +async function reIndexUserMeetingSettings () { + if (userId === null) { + await helper.promptUser(reIndexAllUserMeetingSettingsPrompt, async () => { + try { + await helper.indexBulkDataToES(userMeetingSettingModelOpts, index, logger) + process.exit(0) + } catch (err) { + logger.logFullError(err, { component: 'reIndexUserMeetingSettings' }) + process.exit(1) + } + }) + } else { + await helper.promptUser(reIndexUserMeetingSettingPrompt, async () => { + try { + await helper.indexDataToEsById(userId, userMeetingSettingModelOpts, index, logger) + process.exit(0) + } catch (err) { + logger.logFullError(err, { component: 'reIndexUserMeetingSettings' }) + process.exit(1) + } + }) + } +} + +reIndexUserMeetingSettings() diff --git a/src/bootstrap.js b/src/bootstrap.js index 4c927dc9..fab31ef1 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -7,7 +7,6 @@ const { Interviews, AggregatePaymentStatus, WorkPeriodPaymentStatus, WorkPeriodP const logger = require('./common/logger') const allowedInterviewStatuses = _.values(Interviews.Status) -const allowedXAITemplate = _.keys(Interviews.XaiTemplate) Joi.page = () => Joi.number().integer().min(1).default(1) Joi.perPage = () => Joi.number().integer().min(1).default(20) @@ -20,7 +19,6 @@ Joi.workload = () => Joi.string().valid('full-time', 'fractional') Joi.jobCandidateStatus = () => Joi.string().valid('open', 'placed', 'selected', 'client rejected - screening', 'client rejected - interview', 'rejected - other', 'cancelled', 'interview', 'topcoder-rejected', 'applied', 'rejected-pre-screen', 'skills-test', 'skills-test', 'phone-screen', 'job-closed', 'offered', 'withdrawn', 'withdrawn-prescreen') Joi.title = () => Joi.string().max(128) Joi.paymentStatus = () => Joi.string().valid(..._.values(AggregatePaymentStatus)) -Joi.xaiTemplate = () => Joi.string().valid(...allowedXAITemplate) Joi.interviewStatus = () => Joi.string().valid(...allowedInterviewStatuses) Joi.workPeriodPaymentStatus = () => Joi.string().valid(..._.values(WorkPeriodPaymentStatus)) Joi.workPeriodPaymentUpdateStatus = () => Joi.string().valid(..._.values(WorkPeriodPaymentUpdateStatus)) diff --git a/src/common/helper.js b/src/common/helper.js index 0afca289..ac19a340 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -6,6 +6,7 @@ const fs = require('fs') const querystring = require('querystring') const Confirm = require('prompt-confirm') const Bottleneck = require('bottleneck') +const URI = require('urijs') const AWS = require('aws-sdk') const config = require('config') const HttpStatus = require('http-status-codes') @@ -21,8 +22,10 @@ const models = require('../models') const eventDispatcher = require('./eventDispatcher') const busApi = require('@topcoder-platform/topcoder-bus-api-wrapper') const moment = require('moment-timezone') -const { PaymentStatusRules } = require('../../app-constants') +const { PaymentStatusRules, SearchUsers, InterviewEventHandlerTimeout } = require('../../app-constants') const emailTemplateConfig = require('../../config/email_template.config') +const { Mutex, withTimeout } = require('async-mutex') +const jwt = require('jsonwebtoken') const localLogger = { debug: (message) => @@ -139,24 +142,27 @@ esIndexPropertyMapping[config.get('esConfig.ES_INDEX_JOB_CANDIDATE')] = { type: 'nested', properties: { id: { type: 'keyword' }, - xaiId: { type: 'keyword' }, + nylasPageId: { type: 'keyword' }, + nylasPageSlug: { type: 'keyword' }, + nylasCalendarId: { type: 'keyword' }, + hostTimezone: { type: 'keyword' }, + guestTimezone: { type: 'keyword' }, + availableTime: { + type: 'nested', + properties: { + days: { type: 'keyword' }, + end: { type: 'date', format: 'HH:mm' }, + start: { type: 'date', format: 'HH:mm' } + } + }, + hostUserId: { type: 'keyword' }, + expireTimestamp: { type: 'date' }, jobCandidateId: { type: 'keyword' }, - calendarEventId: { type: 'keyword' }, - templateUrl: { type: 'keyword' }, - templateId: { type: 'keyword' }, - templateType: { type: 'keyword' }, - title: { type: 'keyword' }, - locationDetails: { type: 'keyword' }, duration: { type: 'integer' }, startTimestamp: { type: 'date' }, endTimestamp: { type: 'date' }, - hostName: { type: 'keyword' }, - hostEmail: { type: 'keyword' }, - guestNames: { type: 'keyword' }, - guestEmails: { type: 'keyword' }, round: { type: 'integer' }, status: { type: 'keyword' }, - rescheduleUrl: { type: 'keyword' }, createdAt: { type: 'date' }, createdBy: { type: 'keyword' }, updatedAt: { type: 'date' }, @@ -859,7 +865,6 @@ function getESClient () { if (esClients.client) { return esClients.client } - const host = config.esConfig.HOST const cloudId = config.esConfig.ELASTICCLOUD.id if (cloudId) { @@ -1124,6 +1129,86 @@ async function getUserById (userId, enrich) { return user } +/** + * Function to get users + * @param {String} userId the user UUID + * @returns the found user details + */ +async function getUserDetailsByUserUUID (userUUID) { + const token = await getM2MToken() + const res = await request + .get(`${config.TC_API}/users/${userUUID}?enrich=true`) + .set('Authorization', `Bearer ${token}`) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json') + localLogger.debug({ + context: 'getUserById', + message: `response body: ${JSON.stringify(res.body)}` + }) + const user = _.pick(res.body, ['id', 'handle', 'firstName', 'lastName', 'externalProfiles']) + + if (!_.isUndefined(user.externalProfiles) && !_.isEmpty(user.externalProfiles)) { + _.assign(user, { userId: _.toInteger(_.get(user.externalProfiles[0], 'externalId')) }) + } + + const handleQuery = `handleLower:${user.handle.toLowerCase()}` + const userIdQuery = `userId:${user.userId}` + + const query = _.concat(handleQuery, userIdQuery).join(URI.encodeQuery(' OR ', 'utf8')) + try { + const searchResult = await searchUsersByQuery(query) + const found = _.find(searchResult, !_.isUndefined(user.handle) + ? ['handle', user.handle] : ['userId', user.userId]) || {} + + return found + } catch (err) { + const error = new Error(err.response.text) + error.status = err.status + throw error + } +} + +/** + * Search users by query string. + * @param {String} query the query string + * @returns {Array} the matched users + */ +async function searchUsersByQuery (query) { + const token = await getM2MToken() + let users = [] + // there may be multiple pages, search all pages + let offset = 0 + const limit = SearchUsers.SEARCH_USERS_PAGE_SIZE + // set initial total to 1 so that at least one search is done, + // it will be updated from search result + let total = 1 + while (offset < total) { + const res = await request + .get(`${ + config.TOPCODER_MEMBERS_API_V3 + }/_search?query=${ + query + }&offset=${ + offset + }&limit=${ + limit + }&fields=userId,email,handle,firstName,lastName,photoURL,status`) + .set('Authorization', `Bearer ${token}`) + if (!_.get(res, 'body.result.success')) { + throw new Error(`Failed to search users by query: ${query}`) + } + const records = _.get(res, 'body.result.content') || [] + // add users + users = users.concat(records) + + total = _.get(res, 'body.result.metadata.totalCount') || 0 + offset += limit + } + + logger.verbose(`Searched users: ${JSON.stringify(users)}`) + return users +} + /** * Function to create user in ubahn * @param {Object} data the user data @@ -2088,6 +2173,89 @@ function formatDate (date) { } } +/** + * Runs code one by one for interview event handlers. + * + * @param {Function} func function to execute + * @returns Promise + */ +const interviewsWebhookMutex = withTimeout(new Mutex(), InterviewEventHandlerTimeout) +async function runExclusiveInterviewEventHandler (func) { + return interviewsWebhookMutex.runExclusive(func) +} + +/** + * Runs code one by one for calendar webhooks. + * + * @param {Function} func function to execute + * @returns Promise + */ +const calendarWebhookMutex = new Mutex() +async function waitForUnlockCalendarConnectionHandler (func) { + return calendarWebhookMutex.waitForUnlock().then(func) +} +async function runExclusiveCalendarConnectionHandler (func) { + return calendarWebhookMutex.runExclusive(func) +} + +const namedMutexMap = {} +/** + * Runs code one by one using mutex. + * + * @param {String|Number} mutexName mutex name + * @param {Function} func function to execute + * @returns {Promise} + */ +async function runExclusiveByNamedMutex (mutexName, func) { + // mutex name should be either string or number + if (!(_.isString(mutexName) || _.isNumber(mutexName))) { + throw new Error('Mutex name has to be provided.') + } + + if (!_.isFunction(func)) { + throw new Error('Mutex callback function has to be provided.') + } + + let namedMutex = namedMutexMap[mutexName] + if (!namedMutex) { + namedMutex = new Mutex() + namedMutexMap[mutexName] = namedMutex + } + + return namedMutex.runExclusive(func) +} + +/** + * Sign zoom link. + * + * @param {Object} data the object to sign + * @returns token + */ +function signZoomLink (data) { + return jwt.sign( + data, + config.ZOOM_LINK_SECRET, + { + algorithm: 'HS256', + expiresIn: config.ZOOM_LINK_TOKEN_EXPIRY + } + ) +} + +/** + * Verify zoom link request token. + * + * @param {String} token the token to verify + * @returns data if token is valid + */ +function verifyZoomLinkToken (token) { + try { + return jwt.verify(token, config.ZOOM_LINK_SECRET) + } catch (e) { + throw new errors.UnauthorizedError(`token invalid: ${e.message}`) + } +} + module.exports = { encodeQueryString, getParamFromCliArgs, @@ -2154,5 +2322,12 @@ module.exports = { getMembersSuggest, getEmailTemplatesForKey, formatDate, - formatDateTimeEDT + formatDateTimeEDT, + getUserDetailsByUserUUID, + runExclusiveCalendarConnectionHandler, + waitForUnlockCalendarConnectionHandler, + runExclusiveInterviewEventHandler, + runExclusiveByNamedMutex, + signZoomLink, + verifyZoomLinkToken } diff --git a/src/common/nylas.js b/src/common/nylas.js new file mode 100644 index 00000000..10890ff4 --- /dev/null +++ b/src/common/nylas.js @@ -0,0 +1,98 @@ +/* + * utility function that returns the model schema for + * the JSONB array that maps to Nylas' opening_hours + * + */ + +const { Sequelize } = require('sequelize') +const { Interviews: InterviewConstants } = require('../../app-constants') + +function nylasAvailableTimeSchema (fieldName) { + return { + field: fieldName, + allowNull: false, + type: Sequelize.JSONB({ + type: Sequelize.ARRAY({ + days: { + type: Sequelize.ARRAY({ + type: Sequelize.ENUM( + InterviewConstants.Nylas.Days.Monday, + InterviewConstants.Nylas.Days.Tuesday, + InterviewConstants.Nylas.Days.Wednesday, + InterviewConstants.Nylas.Days.Thursday, + InterviewConstants.Nylas.Days.Friday, + InterviewConstants.Nylas.Days.Saturday, + InterviewConstants.Nylas.Days.Sunday + ) + }) + }, + end: { + type: Sequelize.STRING(5), + allowNull: false + }, + start: { + type: Sequelize.STRING(5), + allowNull: false + }, + allowNull: false + }), + allowNull: false + }) + } +} +function nylasCalendarsSchema () { + return { + field: 'nylasCalendars', + type: Sequelize.JSONB({ + type: Sequelize.ARRAY({ + accessToken: { + field: 'accessToken', + type: Sequelize.STRING(5), + allowNull: false + }, + accountId: { + field: 'accountId', + type: Sequelize.STRING(5), + allowNull: false + }, + accountProvider: { + field: 'accountProvider', + type: Sequelize.STRING(5), + allowNull: false + }, + email: { + field: 'email', + type: Sequelize.STRING, + validate: { + isEmail: { + msg: 'Please provide a valid email address' + } + } + }, + id: { + field: 'id', + type: Sequelize.STRING(5), + allowNull: false + }, + isPrimary: { + field: 'isPrimary', + type: Sequelize.BOOLEAN, + defaultValue: false, + allowNull: false + }, + isDeleted: { + field: 'isDeleted', + type: Sequelize.BOOLEAN, + defaultValue: false, + allowNull: false + } + }), + allowNull: false + }) + } +} + +module.exports = { + nylasAvailableTimeSchema, + nylasCalendarsSchema +} diff --git a/src/controllers/InterviewController.js b/src/controllers/InterviewController.js index 21cceca1..ae09dd21 100644 --- a/src/controllers/InterviewController.js +++ b/src/controllers/InterviewController.js @@ -51,6 +51,15 @@ async function partiallyUpdateInterviewById (req, res) { res.send(await service.partiallyUpdateInterviewById(req.authUser, req.params.id, req.body)) } +/** + * Patch (partially update) interview by Nylas webhook + * @param req the request + * @param res the response + */ +async function partiallyUpdateInterviewByWebhook (req, res) { + res.send(await service.partiallyUpdateInterviewByWebhook(req.params.id, req.query.authToken, req.body)) +} + /** * Search interviews * @param req the request @@ -62,11 +71,23 @@ async function searchInterviews (req, res) { res.send(result.result) } +/** + * Get a fresh Zoom Links from Zoom Meeting and redirect to Zoom Link + * @param req the request + * @param res the response + */ +async function getZoomLink (req, res) { + const zoomLink = await service.getZoomLink(req.params.id, req.query) + return res.redirect(zoomLink) +} + module.exports = { getInterviewByRound, getInterviewById, requestInterview, partiallyUpdateInterviewByRound, partiallyUpdateInterviewById, - searchInterviews + searchInterviews, + partiallyUpdateInterviewByWebhook, + getZoomLink } diff --git a/src/controllers/UserMeetingSettingsController.js b/src/controllers/UserMeetingSettingsController.js new file mode 100644 index 00000000..40003996 --- /dev/null +++ b/src/controllers/UserMeetingSettingsController.js @@ -0,0 +1,43 @@ +/** + * Controller for UserMeetingSettings endpoints + */ +const service = require('../services/UserMeetingSettingsService') +const helper = require('../common/helper') +const { StatusCodes } = require('http-status-codes') + +/** + * Get UserMeetingSettings for the provided userId + * @param req the request + * @param res the response + */ +async function getUserMeetingSettingsByUserId (req, res) { + const result = await service.getUserMeetingSettingsByUserId(req.authUser, req.params.userId, req.query.fromDb) + helper.setResHeaders(req, res, result) + res.send(result) +} + +/** + * Handle calendar connection callback for user + * @param req the request + * @param res the response + */ +async function handleConnectCalendarCallback (req, res) { + const redirectUrl = await service.handleConnectCalendarCallback(req.query) + res.redirect(redirectUrl) +} + +/** + * Delete an existing calendar for user + * @param req the request + * @param res the response + */ +async function deleteUserCalendar (req, res) { + await service.deleteUserCalendar(req.authUser, req.params) + res.status(StatusCodes.NO_CONTENT).end() +} + +module.exports = { + getUserMeetingSettingsByUserId, + handleConnectCalendarCallback, + deleteUserCalendar +} diff --git a/src/controllers/WebhookController.js b/src/controllers/WebhookController.js new file mode 100644 index 00000000..cc44bf2d --- /dev/null +++ b/src/controllers/WebhookController.js @@ -0,0 +1,18 @@ +/** + * Controller for webhook endpoints + */ +const nylasWebhookService = require('../services/NylasWebhookService') + +async function nylasWebhook (req, res) { + await nylasWebhookService.nylasWebhook(req, res) +} + +async function nylasWebhookCheck (req, res) { + const result = await nylasWebhookService.nylasWebhookCheck(req, res) + res.send(result) +} + +module.exports = { + nylasWebhook, + nylasWebhookCheck +} diff --git a/src/esProcessors/UserMeetingSettingsProcessor.js b/src/esProcessors/UserMeetingSettingsProcessor.js new file mode 100644 index 00000000..7d2ac747 --- /dev/null +++ b/src/esProcessors/UserMeetingSettingsProcessor.js @@ -0,0 +1,84 @@ +/** + * UserMeetingSettings Processor + */ + +const config = require('config') +const helper = require('../common/helper') +const _ = require('lodash') + +const esClient = helper.getESClient() + +/** + * Process create entity + * @param {Object} entity entity object + */ +async function processCreate (entity) { + await esClient.create({ + index: config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS'), + id: entity.id, + body: entity, + refresh: 'wait_for' + }) +} + +/** + * Process update entity + * @param {Object} entity entity object + */ +async function processUpdate (entity) { + await esClient.update({ + index: config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS'), + id: entity.id, + body: { + doc: entity + }, + refresh: 'wait_for' + }) +} + +/** + * Process delete entity + * @param {Object} entity entity object + */ +async function processDelete (entity) { + await esClient.delete({ + index: config.get('esConfig.ES_INDEX_USER_MEETING_SETTINGS'), + id: entity.id, + refresh: 'wait_for' + }) +} + +/** + * Creates if records doesn't exist and updates if exists + * @param {Object} entity entity object + */ +async function processCreateOrUpdate (entity) { + let userMeetingSettingsESResponse + try { + userMeetingSettingsESResponse = await esClient.get({ + index: config.esConfig.ES_INDEX_USER_MEETING_SETTINGS, + id: entity.id + }) + + // if records already exist, then update + if (_.get(userMeetingSettingsESResponse, 'body._source')) { + await processUpdate(entity) + } else { + await processCreate(entity) + } + } catch (err) { + // if error happens due to missing document, then try to create it + if (helper.isDocumentMissingException(err)) { + await processCreate(entity) + } else { + throw err + } + } +} + +module.exports = { + processCreate, + processUpdate, + processDelete, + processCreateOrUpdate +} diff --git a/src/eventHandlers/InterviewEventHandler.js b/src/eventHandlers/InterviewEventHandler.js index 034c1a8f..76b29825 100644 --- a/src/eventHandlers/InterviewEventHandler.js +++ b/src/eventHandlers/InterviewEventHandler.js @@ -4,37 +4,427 @@ const { Op } = require('sequelize') const _ = require('lodash') +const moment = require('moment-timezone') const config = require('config') const models = require('../models') const logger = require('../common/logger') const helper = require('../common/helper') -const teamService = require('../services/TeamService') const Constants = require('../../app-constants') +const notificationsSchedulerService = require('../services/NotificationsSchedulerService') +const Interview = models.Interview +const { generateZoomMeetingLink, updateZoomMeeting, cancelZoomMeeting } = require('../services/ZoomService') +const { processUpdateInterview } = require('../esProcessors/InterviewProcessor') +/** + * Send interview invitaion notifications + * @param {*} interview the requested interview + * @returns + */ +async function sendInterviewInvitationNotifications (interview) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewInvitationNotifications', + message: `send to interview ${interview.id}` + }) + + try { + const template = 'taas.notification.interview-invitation' + + // const jobCandidate = await models.JobCandidate.findById(interview.jobCandidateId) + // const { email, firstName, lastName } = await helper.getUserDetailsByUserUUID(interview.hostUserId) + + // send host email + const data = await notificationsSchedulerService.getDataForInterview(interview) + if (!data) { return } + + if (!_.isEmpty(data.guestEmail)) { + // send guest emails + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.guestEmail }], + data: { + ...data, + subject: `${data.duration} minutes tech interview with ${data.guestFullName} for ${data.jobTitle} is requested by the Customer`, + nylasPageSlug: interview.nylasPageSlug + } + }) + } else { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewInvitationNotifications', + message: `Interview id: ${interview.id} guest emails not present` + }) + } + } catch (e) { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewInvitationNotifications', + message: `Send email to interview ${interview.id}: ${e}` + }) + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewInvitationNotifications', + message: `Sent notifications for interview ${interview.id}` + }) +} /** - * Once we request Interview for a JobCandidate, the invitation emails to be sent out. - * - * @param {Object} payload the event payload - * @returns {undefined} + * Send interview scheduled notifications + * @param {*} interview the interview + * @returns */ -async function sendInvitationEmail (payload) { +async function sendInterviewScheduledNotifications (payload) { const interview = payload.value - // get customer details via job candidate user - const jobCandidate = await models.JobCandidate.findById(interview.jobCandidateId) - const job = await jobCandidate.getJob() - teamService.sendEmail({}, { - template: 'interview-invitation', - cc: [interview.hostEmail, ...interview.guestEmails], - data: { - interview_id: interview.id, - interview_round: interview.round, - interviewee_name: interview.guestNames[0], - interviewer_name: interview.hostName, - xai_template: '/' + interview.templateUrl, - additional_interviewers_name: (interview.guestNames.slice(1)).join(','), - interview_length: interview.duration, - job_name: job.title + const interviewOldValue = payload.options.oldValue + + if (interview.status === interviewOldValue.status) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: 'not interested in interview - interview status is not changed' + }) + return + } + + if (!_.includes([Constants.Interviews.Status.Scheduled, Constants.Interviews.Status.Rescheduled], interview.status)) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: `not interested in interview - status: ${interview.status}` + }) + return + } + + // if interview already has timestamp it means rescheduling interview + if (interviewOldValue.startTimestamp) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: 'not interested in interview - it already has startTimestamp' + }) + return + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: `sending for interview ${interview.id}` + }) + + try { + const template = 'taas.notification.interview-link-for-host' + + const TIME_FORMAT = 'dddd MMM. Do, hh:mm a' + + const interviewEntity = await Interview.findOne({ + where: { + [Op.or]: [ + { id: interview.id } + ] + } + }) + // send host email + const data = await notificationsSchedulerService.getDataForInterview(interviewEntity) + if (!data) { return } + + const { meeting, zoomAccountApiKey } = await generateZoomMeetingLink(interviewEntity.startTimestamp, interviewEntity.duration) + + const updatedInterview = await interviewEntity.update({ zoomAccountApiKey, zoomMeetingId: meeting.id }) + await processUpdateInterview(updatedInterview.toJSON()) + + const interviewCancelLink = `${config.TAAS_APP_BASE_URL}/interview/${interview.id}/cancel` + const interviewRescheduleLink = `${config.TAAS_APP_BASE_URL}/interview/${interview.id}/reschedule` + + const hostZoomToken = helper.signZoomLink({ type: Constants.ZoomLinkType.HOST, id: interview.id }) + const hostZoomLink = `${config.TAAS_API_BASE_URL}/getInterview/${interview.id}/zoom-link?type=${Constants.ZoomLinkType.HOST}&token=${hostZoomToken}` + + const guestZoomToken = helper.signZoomLink({ type: Constants.ZoomLinkType.GUEST, id: interview.id }) + const guestZoomLink = `${config.TAAS_API_BASE_URL}/getInterview/${interview.id}/zoom-link?type=${Constants.ZoomLinkType.GUEST}&token=${guestZoomToken}` + + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.hostEmail }], + data: { + host: data.hostFullName, + guest: data.guestFullName, + jobTitle: data.jobTitle, + zoomLink: hostZoomLink, + start: moment(interview.startTimestamp).tz(interviewEntity.hostTimezone).format(TIME_FORMAT) + ` ${interviewEntity.hostTimezone}`, + end: moment(interview.endTimestamp).tz(interviewEntity.hostTimezone).format(TIME_FORMAT) + ` ${interviewEntity.hostTimezone}`, + hostTimezone: interviewEntity.hostTimezone, + interviewCancelLink, + interviewRescheduleLink + } + }) + + if (!_.isEmpty(data.guestEmail)) { + const template = 'taas.notification.interview-link-for-guest' + // fallback to host timezone if by some reason we didn't obtain guest timezone + const guestTimezone = interviewEntity.guestTimezone || interviewEntity.hostTimezone + // send guest emails + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.guestEmail }], + data: { + host: data.hostFullName, + guest: data.guestFullName, + jobTitle: data.jobTitle, + zoomLink: guestZoomLink, + start: moment(interview.startTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + end: moment(interview.endTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + guestTimezone, + interviewCancelLink, + interviewRescheduleLink + } + }) + } else { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: `Interview id: ${interview.id} guest emails not present` + }) } + } catch (e) { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: `Send email to interview ${interview.id}: ${e}` + }) + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewScheduledNotifications', + message: `Sent notifications for interview ${interview.id}` + }) +} + +/** + * Send interview rescheduled notifications + * @param {*} interview the interview + * @returns + */ +async function sendInterviewRescheduledNotifications (payload) { + const interview = payload.value + const interviewOldValue = payload.options.oldValue + + if (!_.includes([Constants.Interviews.Status.Scheduled, Constants.Interviews.Status.Rescheduled], interview.status)) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: `not interested in interview - status: ${interview.status}` + }) + return + } + + // interview is rescheduled it had startTimestamp before, and it has startTimestamp now + if (!interviewOldValue.startTimestamp || !interview.startTimestamp) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: 'not interested in interview - didn\'t have or doesn\'t have startTimestamp ' + }) + return + } + + if (moment(interview.startTimestamp).isSame(interviewOldValue.startTimestamp)) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: 'not interested in interview - interview has same startTime' + }) + return + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: `sending for interview ${interview.id}` + }) + + try { + const template = 'taas.notification.interview-rescheduled-host' + + const TIME_FORMAT = 'dddd MMM. Do, hh:mm a' + + const interviewEntity = await Interview.findOne({ + where: { + [Op.or]: [ + { id: interview.id } + ] + } + }) + // send host email + const data = await notificationsSchedulerService.getDataForInterview(interviewEntity) + if (!data) { return } + + await updateZoomMeeting(interviewEntity.startTimestamp, interviewEntity.duration, interviewEntity.zoomAccountApiKey, interviewEntity.zoomMeetingId) + + const interviewCancelLink = `${config.TAAS_APP_BASE_URL}/interview/${interview.id}/cancel` + const interviewRescheduleLink = `${config.TAAS_APP_BASE_URL}/interview/${interview.id}/reschedule` + + const hostZoomToken = helper.signZoomLink({ type: Constants.ZoomLinkType.HOST, id: interview.id }) + const hostZoomLink = `${config.TAAS_API_BASE_URL}/getInterview/${interview.id}/zoom-link?type=${Constants.ZoomLinkType.HOST}&token=${hostZoomToken}` + + const guestZoomToken = helper.signZoomLink({ type: Constants.ZoomLinkType.GUEST, id: interview.id }) + const guestZoomLink = `${config.TAAS_API_BASE_URL}/getInterview/${interview.id}/zoom-link?type=${Constants.ZoomLinkType.GUEST}&token=${guestZoomToken}` + + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.hostEmail }], + data: { + host: data.hostFullName, + guest: data.guestFullName, + jobTitle: data.jobTitle, + zoomLink: hostZoomLink, + oldStart: moment(interviewOldValue.startTimestamp).tz(interviewEntity.hostTimezone).format(TIME_FORMAT) + ` ${interviewEntity.hostTimezone}`, + start: moment(interview.startTimestamp).tz(interviewEntity.hostTimezone).format(TIME_FORMAT) + ` ${interviewEntity.hostTimezone}`, + end: moment(interview.endTimestamp).tz(interviewEntity.hostTimezone).format(TIME_FORMAT) + ` ${interviewEntity.hostTimezone}`, + hostTimezone: interviewEntity.hostTimezone, + interviewCancelLink, + interviewRescheduleLink + } + }) + + if (!_.isEmpty(data.guestEmail)) { + const template = 'taas.notification.interview-rescheduled-guest' + // fallback to host timezone if by some reason we didn't obtain guest timezone + const guestTimezone = interviewEntity.guestTimezone || interviewEntity.hostTimezone + // send guest emails + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.guestEmail }], + data: { + host: data.hostFullName, + guest: data.guestFullName, + jobTitle: data.jobTitle, + zoomLink: guestZoomLink, + oldStart: moment(interviewOldValue.startTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + start: moment(interview.startTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + end: moment(interview.endTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + guestTimezone, + interviewCancelLink, + interviewRescheduleLink + } + }) + } else { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: `Interview id: ${interview.id} guest emails not present` + }) + } + } catch (e) { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: `Send email to interview ${interview.id}: ${e}` + }) + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewRescheduledNotifications', + message: `Sent notifications for interview ${interview.id}` + }) +} + +/** + * Send interview cancelled notifications + * @param {*} interview the interview + * @returns + */ +async function sendInterviewCancelledNotifications (payload) { + const interview = payload.value + const interviewOldValue = payload.options.oldValue + + if (!_.includes([Constants.Interviews.Status.Scheduled, Constants.Interviews.Status.Rescheduled], interviewOldValue.status)) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewCancelledNotifications', + message: `interview status ${interviewOldValue.status} can not be cancelled` + }) + return + } + if (interview.status !== Constants.Interviews.Status.Cancelled) { + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewCancelledNotifications', + message: `not interested in interview - status: ${interview.status}` + }) + return + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewCancelledNotifications', + message: `sending for interview ${interview.id}` + }) + + try { + const template = 'taas.notification.interview-cancelled-host' + + const TIME_FORMAT = 'dddd MMM. Do, hh:mm a' + + const interviewEntity = await Interview.findOne({ + where: { + [Op.or]: [ + { id: interview.id } + ] + } + }) + // send host email + const data = await notificationsSchedulerService.getDataForInterview(interviewEntity) + if (!data) { return } + + await cancelZoomMeeting(interviewEntity.zoomAccountApiKey, interviewEntity.zoomMeetingId) + + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.hostEmail }], + data: { + host: data.hostFullName, + guest: data.guestFullName, + jobTitle: data.jobTitle, + start: moment(interview.startTimestamp).tz(interviewEntity.hostTimezone).format(TIME_FORMAT) + ` ${interviewEntity.hostTimezone}` + } + }) + + if (!_.isEmpty(data.guestEmail)) { + const template = 'taas.notification.interview-cancelled-guest' + // fallback to host timezone if by some reason we didn't obtain guest timezone + const guestTimezone = interviewEntity.guestTimezone || interviewEntity.hostTimezone + // send guest emails + await notificationsSchedulerService.sendNotification({}, { + template, + recipients: [{ email: data.guestEmail }], + data: { + host: data.hostFullName, + guest: data.guestFullName, + jobTitle: data.jobTitle, + start: moment(interview.startTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}` + } + }) + } else { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewCancelledNotifications', + message: `Interview id: ${interview.id} guest emails not present` + }) + } + } catch (e) { + logger.error({ + component: 'InterviewEventHandler', + context: 'sendInterviewCancelledNotifications', + message: `Send email to interview ${interview.id}: ${e}` + }) + } + + logger.debug({ + component: 'InterviewEventHandler', + context: 'sendInterviewCancelledNotifications', + message: `Sent notifications for interview ${interview.id}` }) } @@ -108,11 +498,7 @@ async function checkOverlapping (payload) { recipients: (template.recipients || []).map(email => ({ email })), data: { subject: template.subject, - interviews, - notificationType: { - overlappingInterview: true - }, - description: 'Overlapping Job Candidate Interviews' + interviews }, sendgridTemplateId: template.sendgridTemplateId, version: 'v3' @@ -169,7 +555,7 @@ async function checkOverlapping (payload) { * @returns {undefined} */ async function processRequest (payload) { - await sendInvitationEmail(payload) + await sendInterviewInvitationNotifications(payload.value) await checkOverlapping(payload) } @@ -180,6 +566,9 @@ async function processRequest (payload) { * @returns {undefined} */ async function processUpdate (payload) { + await sendInterviewRescheduledNotifications(payload) + await sendInterviewCancelledNotifications(payload) + await sendInterviewScheduledNotifications(payload) await checkOverlapping(payload) } diff --git a/src/eventHandlers/JobCandidateEventHandler.js b/src/eventHandlers/JobCandidateEventHandler.js index b61ece91..5c5fc6ed 100644 --- a/src/eventHandlers/JobCandidateEventHandler.js +++ b/src/eventHandlers/JobCandidateEventHandler.js @@ -165,11 +165,7 @@ async function sendJobCandidateSelectedNotification (payload) { jobStartDate: helper.formatDate(job.startDate), userHandle: user.handle, jobUrl, - rcrmJobUrl, - notificationType: { - candidateSelected: true - }, - description: 'Job Candidate Selected' + rcrmJobUrl } data.subject = helper.substituteStringByObject(data.subject, data) const emailData = { diff --git a/src/eventHandlers/JobEventHandler.js b/src/eventHandlers/JobEventHandler.js index 7ff989f6..cc110d6e 100644 --- a/src/eventHandlers/JobEventHandler.js +++ b/src/eventHandlers/JobEventHandler.js @@ -91,11 +91,7 @@ async function sendNotifications (payload) { jobTitle: payload.value.title, jobURL: `${config.TAAS_APP_URL}/${project.id}/positions/${payload.value.id}`, jobDuration: payload.value.duration, - jobStartDate: helper.formatDate(payload.value.startDate), - notificationType: { - newJobCreated: true - }, - description: 'New Job Created' + jobStartDate: helper.formatDate(payload.value.startDate) } data.subject = helper.substituteStringByObject(data.subject, data) diff --git a/src/eventHandlers/ResourceBookingEventHandler.js b/src/eventHandlers/ResourceBookingEventHandler.js index de4f125e..7b20427a 100644 --- a/src/eventHandlers/ResourceBookingEventHandler.js +++ b/src/eventHandlers/ResourceBookingEventHandler.js @@ -97,11 +97,7 @@ async function sendPlacedNotifications (payload) { jobUrl, userHandle: user.handle, startDate: resourceBooking.startDate, - endDate: resourceBooking.endDate, - notificationType: { - resourceBookingPlaced: true - }, - description: 'Resource Booking is Placed' + endDate: resourceBooking.endDate } data.subject = helper.substituteStringByObject(data.subject, data) const emailData = { diff --git a/src/eventHandlers/TeamEventHandler.js b/src/eventHandlers/TeamEventHandler.js index fe7b7f23..8e83ebf6 100644 --- a/src/eventHandlers/TeamEventHandler.js +++ b/src/eventHandlers/TeamEventHandler.js @@ -24,11 +24,7 @@ async function sendNotificationEmail (payload) { duration: j.duration, startDate: helper.formatDate(j.startDate), jobUrl: `${config.TAAS_APP_URL}/${payload.project.id}/positions/${j.id}` - })), - notificationType: { - newTeamCreated: true - }, - description: 'New Team Created' + })) } data.subject = helper.substituteStringByObject(data.subject, data) diff --git a/src/models/Interview.js b/src/models/Interview.js index 23dbb152..068fd84f 100644 --- a/src/models/Interview.js +++ b/src/models/Interview.js @@ -3,6 +3,7 @@ const config = require('config') const _ = require('lodash') const { Interviews } = require('../../app-constants') const errors = require('../common/errors') +const { nylasAvailableTimeSchema } = require('../common/nylas') // allowed status values const statuses = _.values(Interviews.Status) @@ -33,6 +34,23 @@ module.exports = (sequelize) => { } return interview } + + /** + * Get interview by Nylas Event Id + * @param {String} nylasEventId Nylas Event Id + * @returns {Interview} the Interview instance + */ + static async findByNylasEventId (nylasEventId) { + const interview = await Interview.findOne({ + where: { + nylasEventId + } + }) + if (!interview) { + throw new errors.NotFoundError(`"Interview" doesn't exist with nylasEventId: "${nylasEventId}"`) + } + return interview + } } Interview.init( { @@ -42,39 +60,58 @@ module.exports = (sequelize) => { allowNull: false, defaultValue: Sequelize.UUIDV4 }, - xaiId: { - field: 'xai_id', - type: Sequelize.STRING(255) + nylasPageId: { + field: 'nylas_page_id', + type: Sequelize.STRING(255), + allowNull: false }, - jobCandidateId: { - field: 'job_candidate_id', - type: Sequelize.UUID, + nylasPageSlug: { + field: 'nylas_page_slug', + type: Sequelize.STRING(255), allowNull: false }, - calendarEventId: { - field: 'calendar_event_id', - type: Sequelize.STRING(255) + nylasCalendarId: { + field: 'nylas_calendar_id', + type: Sequelize.STRING(255), + allowNull: false }, - templateUrl: { - field: 'template_url', + nylasEventId: { + field: 'nylas_event_id', + type: Sequelize.STRING(255), + allowNull: true, + defaultValue: null + }, + nylasEventEditHash: { + field: 'nylas_event_edit_hash', + type: Sequelize.STRING(255), + allowNull: true, + defaultValue: null + }, + hostTimezone: { + field: 'host_timezone', type: Sequelize.STRING(255), allowNull: false }, - templateId: { - field: 'template_id', - type: Sequelize.STRING(255) + guestTimezone: { + field: 'guest_timezone', + type: Sequelize.STRING(255), + allowNull: true }, - templateType: { - field: 'template_type', - type: Sequelize.STRING(255) + availableTime: nylasAvailableTimeSchema('availableTime'), + hostUserId: { + field: 'hostUserId', + type: Sequelize.UUID, + allowNull: false }, - title: { - field: 'title', - type: Sequelize.STRING(255) + expireTimestamp: { + field: 'expireTimestamp', + type: Sequelize.DATE, + allowNull: true }, - locationDetails: { - field: 'location_details', - type: Sequelize.STRING(255) + jobCandidateId: { + field: 'job_candidate_id', + type: Sequelize.UUID, + allowNull: false }, duration: { field: 'duration', @@ -92,30 +129,20 @@ module.exports = (sequelize) => { field: 'end_timestamp', type: Sequelize.DATE }, - hostName: { - field: 'host_name', - type: Sequelize.STRING(255) - }, - hostEmail: { - field: 'host_email', - type: Sequelize.STRING(255) - }, - guestNames: { - field: 'guest_names', - type: Sequelize.ARRAY(Sequelize.STRING) + zoomAccountApiKey: { + field: 'zoom_account_api_key', + type: Sequelize.STRING(255), + allowNull: true }, - guestEmails: { - field: 'guest_emails', - type: Sequelize.ARRAY(Sequelize.STRING) + zoomMeetingId: { + field: 'zoom_meeting_id', + type: Sequelize.BIGINT, + allowNull: true }, status: { type: Sequelize.ENUM(statuses), allowNull: false }, - rescheduleUrl: { - field: 'reschedule_url', - type: Sequelize.STRING(255) - }, createdBy: { field: 'created_by', type: Sequelize.UUID, diff --git a/src/models/UserMeetingSettings.js b/src/models/UserMeetingSettings.js new file mode 100644 index 00000000..0b3a3228 --- /dev/null +++ b/src/models/UserMeetingSettings.js @@ -0,0 +1,103 @@ +const { Sequelize, Model } = require('sequelize') +const _ = require('lodash') +const config = require('config') +const errors = require('../common/errors') +const { nylasAvailableTimeSchema, nylasCalendarsSchema } = require('../common/nylas') + +module.exports = (sequelize) => { + class UserMeetingSettings extends Model { + /** + * Get UserMeetingSettings by userId + * @param {String} userId + * @returns {UserMeetingSettings} the UserMeetingSettings instance + */ + static async findById (id) { + const userMeetingSettings = await UserMeetingSettings.findOne({ + where: { + id: id + } + }) + if (!userMeetingSettings) { + throw new errors.NotFoundError(`id: ${id} "UserMeetingSettings" doesn't exist.`) + } + return userMeetingSettings + } + + /** + * Get UserMeetingSettings by userId + * @param {String} userId + * @returns {UserMeetingSettings} the NylasCalendar for the user + */ + static async getPrimaryNylasCalendarForUser (id) { + const calendar = await UserMeetingSettings.findById(id) + .catch(() => null) // in case records is not found + .then(ums => { + // NOTE: ums can bee `null` here + const calendars = _.get(ums, 'nylasCalendars', []) + const notDeletedCalendars = _.reject(calendars, { isDeleted: true }) + return _.find(notDeletedCalendars, { isPrimary: true }) + }) + + return calendar + } + } + UserMeetingSettings.init( + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4 + }, + defaultAvailableTime: nylasAvailableTimeSchema('defaultAvailableTime'), + defaultTimezone: { + field: 'defaultTimezone', + type: Sequelize.STRING(255) + }, + nylasCalendars: nylasCalendarsSchema(), + createdBy: { + field: 'created_by', + type: Sequelize.UUID, + allowNull: false + }, + updatedBy: { + field: 'updated_by', + type: Sequelize.UUID + }, + createdAt: { + field: 'created_at', + type: Sequelize.DATE + }, + updatedAt: { + field: 'updated_at', + type: Sequelize.DATE + }, + deletedAt: { + field: 'deleted_at', + type: Sequelize.DATE + } + }, + { + schema: config.DB_SCHEMA_NAME, + sequelize, + tableName: 'user_meeting_settings', + paranoid: false, + deletedAt: 'deletedAt', + createdAt: 'createdAt', + updatedAt: 'updatedAt', + timestamps: true, + defaultScope: { + attributes: { + exclude: ['deletedAt'] + } + }, + hooks: { + afterCreate: (workPeriodPayment) => { + delete workPeriodPayment.dataValues.deletedAt + } + } + } + ) + + return UserMeetingSettings +} diff --git a/src/routes/InterviewRoutes.js b/src/routes/InterviewRoutes.js index e4a419ad..96ff32a3 100644 --- a/src/routes/InterviewRoutes.js +++ b/src/routes/InterviewRoutes.js @@ -28,6 +28,12 @@ module.exports = { scopes: [constants.Scopes.UPDATE_INTERVIEW, constants.Scopes.ALL_INTERVIEW] } }, + '/updateInterview/:id/nylas-webhooks': { + post: { + controller: 'InterviewController', + method: 'partiallyUpdateInterviewByWebhook' + } + }, '/jobCandidates/:jobCandidateId/interviews': { get: { controller: 'InterviewController', @@ -51,5 +57,11 @@ module.exports = { auth: 'jwt', scopes: [constants.Scopes.READ_INTERVIEW, constants.Scopes.ALL_INTERVIEW] } + }, + '/getInterview/:id/zoom-link': { + get: { + controller: 'InterviewController', + method: 'getZoomLink' + } } } diff --git a/src/routes/TeamRoutes.js b/src/routes/TeamRoutes.js index 92156bdb..a8c90396 100644 --- a/src/routes/TeamRoutes.js +++ b/src/routes/TeamRoutes.js @@ -40,6 +40,22 @@ module.exports = { method: 'getSkillsByJobDescription' } }, + /** + * Nylas Webhook Route + * + * IMPORTANT, don't forget to update this route in `app.js` if you change it + * as we are using a special middleware for this route + */ + '/taas-teams/nylas-webhooks': { + post: { + controller: 'WebhookController', + method: 'nylasWebhook' + }, + get: { + controller: 'WebhookController', + method: 'nylasWebhookCheck' + } + }, '/taas-teams/:id': { get: { controller: 'TeamController', diff --git a/src/routes/UserMeetingSettingsRoutes.js b/src/routes/UserMeetingSettingsRoutes.js new file mode 100644 index 00000000..5fa58f30 --- /dev/null +++ b/src/routes/UserMeetingSettingsRoutes.js @@ -0,0 +1,31 @@ +/** + * Contains User Meetings Settings routes + * + * NOTE: we use `/taas-teams` as a prefix, so we don't have to config Topcoder Gateway separately for these routes. + */ +const constants = require('../../app-constants') + +module.exports = { + '/taas-teams/user-meeting-settings/callback': { + get: { + controller: 'UserMeetingSettingsController', + method: 'handleConnectCalendarCallback' + } + }, + '/taas-teams/user-meeting-settings/:userId/calendars/:calendarId': { + delete: { + controller: 'UserMeetingSettingsController', + method: 'deleteUserCalendar', + auth: 'jwt', + scopes: [constants.Scopes.UPDATE_USER_MEETING_SETTINGS, constants.Scopes.ALL_USER_MEETING_SETTINGS] + } + }, + '/taas-teams/user-meeting-settings/:userId': { + get: { + controller: 'UserMeetingSettingsController', + method: 'getUserMeetingSettingsByUserId', + auth: 'jwt', + scopes: [constants.Scopes.READ_USER_MEETING_SETTINGS, constants.Scopes.ALL_USER_MEETING_SETTINGS] + } + } +} diff --git a/src/services/InterviewService.js b/src/services/InterviewService.js index 4ed04c13..5ec5402a 100644 --- a/src/services/InterviewService.js +++ b/src/services/InterviewService.js @@ -7,8 +7,9 @@ const Joi = require('joi') const moment = require('moment') const config = require('config') const { Op, ForeignKeyConstraintError } = require('sequelize') -const { v4: uuid, validate: uuidValidate } = require('uuid') -const { Interviews: InterviewConstants } = require('../../app-constants') +const { v4: uuid } = require('uuid') +const { createHash } = require('crypto') +const { Interviews: InterviewConstants, ZoomLinkType } = require('../../app-constants') const helper = require('../common/helper') const logger = require('../common/logger') const errors = require('../common/errors') @@ -18,25 +19,62 @@ const { processUpdateInterview, processBulkUpdateInterviews } = require('../esProcessors/InterviewProcessor') + const { processUpdate: jobCandidateProcessUpdate } = require('../esProcessors/JobCandidateProcessor') const sequelize = models.sequelize const Interview = models.Interview +const UserMeetingSettings = models.UserMeetingSettings const esClient = helper.getESClient() +const { + createSchedulingPage, + createVirtualCalendarForUser, + patchSchedulingPage +} = require('./NylasService') +const { + updateEvent +} = require('./NylasService') +const UserMeetingSettingsService = require('./UserMeetingSettingsService') +const { runExclusiveInterviewEventHandler } = require('../common/helper') +const { getZoomMeeting } = require('./ZoomService') + +// Each request made by Nylas in the partiallyUpdateInterviewByWebhook endpoint +// includes a SHA256 hash of a secret (stored in env variable) to be sent in the +// request param. Verifying this hash lets us authenticate the request. +function verifyNylasWebhookRequest (authToken) { + const digest = createHash('sha256') + .update(config.NYLAS_SCHEDULER_WEBHOOK_SECRET) + .digest('hex') + + return digest === authToken +} /** * Ensures user is permitted for the operation. * * @param {Object} currentUser the user who perform this operation. * @param {String} jobCandidateId the job candidate id + * @param {Boolean} allowCandidate will allow also the currentUser to access if is a candidate * @throws {errors.ForbiddenError} */ -async function ensureUserIsPermitted (currentUser, jobCandidateId) { +async function ensureUserIsPermitted (currentUser, jobCandidateId, allowCandidate = false) { if (!currentUser.hasManagePermission && !currentUser.isMachine) { const jobCandidate = await models.JobCandidate.findById(jobCandidateId) const job = await jobCandidate.getJob() - await helper.checkIsMemberOfProject(currentUser.userId, job.projectId) + try { + await helper.checkIsMemberOfProject(currentUser.userId, job.projectId) + } catch (error) { + if (error instanceof errors.UnauthorizedError) { + if (allowCandidate === true) { + const userId = await helper.getUserId(currentUser.userId) + if (userId === jobCandidate.userId) { + return + } + } + } + throw new errors.ForbiddenError('You are not allowed to perform this action!') + } } } @@ -47,7 +85,7 @@ async function ensureUserIsPermitted (currentUser, jobCandidateId) { */ function handleSequelizeError (err, jobCandidateId) { // jobCandidateId doesn't exist - gracefully handle - if (err instanceof ForeignKeyConstraintError) { + if (err instanceof ForeignKeyConstraintError || err instanceof errors.NotFoundError) { throw new errors.NotFoundError( `The job candidate with id=${jobCandidateId} doesn't exist.` ) @@ -69,7 +107,7 @@ function handleSequelizeError (err, jobCandidateId) { */ async function getInterviewByRound (currentUser, jobCandidateId, round, fromDb = false) { // check permission - await ensureUserIsPermitted(currentUser, jobCandidateId) + await ensureUserIsPermitted(currentUser, jobCandidateId, true) if (!fromDb) { try { // get job candidate from ES @@ -118,7 +156,7 @@ getInterviewByRound.schema = Joi.object().keys({ /** * Get interview by id * @param {Object} currentUser the user who perform this operation. - * @param {String} id the interview or xai id + * @param {String} id the interview * @param {Boolean} fromDb flag if query db for data or not * @returns {Object} the interview */ @@ -149,14 +187,6 @@ async function getInterviewById (currentUser, id, fromDb = false) { } } }) - // xaiId - esQueryBody.query.nested.query.bool.should.push({ - term: { - 'interviews.xaiId': { - value: id - } - } - }) // search const { body } = await esClient.search({ index: config.esConfig.ES_INDEX_JOB_CANDIDATE, @@ -166,11 +196,11 @@ async function getInterviewById (currentUser, id, fromDb = false) { const interview = _.get(body, 'hits.hits[0].inner_hits.interviews.hits.hits[0]._source') if (interview) { // check permission before returning - await ensureUserIsPermitted(currentUser, interview.jobCandidateId) + await ensureUserIsPermitted(currentUser, interview.jobCandidateId, true) return interview } // if reaches here, the interview with this IDs is not found - throw new errors.NotFoundError(`Interview doesn't exist with id/xaiId: ${id}`) + throw new errors.NotFoundError(`Interview doesn't exist with id: ${id}`) } catch (err) { logger.logFullError(err, { component: 'InterviewService', context: 'getInterviewById' }) throw err @@ -178,30 +208,19 @@ async function getInterviewById (currentUser, id, fromDb = false) { } // either ES query failed or `fromDb` is set - fallback to DB logger.info({ component: 'InterviewService', context: 'getInterviewById', message: 'try to query db for data' }) - var interview - if (uuidValidate(id)) { - interview = await Interview.findOne({ - where: { - [Op.or]: [ - { id } - ] - } - }) - } else { - interview = await Interview.findOne({ - where: { - [Op.or]: [ - { xaiId: id } - ] - } - }) - } + const interview = await Interview.findOne({ + where: { + [Op.or]: [ + { id } + ] + } + }) // throw NotFound error if doesn't exist if (!!interview !== true) { - throw new errors.NotFoundError(`Interview doesn't exist with id/xaiId: ${id}`) + throw new errors.NotFoundError(`Interview doesn't exist with id: ${id}`) } // check permission before returning - await ensureUserIsPermitted(currentUser, interview.jobCandidateId) + await ensureUserIsPermitted(currentUser, interview.jobCandidateId, true) return interview.dataValues } @@ -223,6 +242,15 @@ async function requestInterview (currentUser, jobCandidateId, interview) { // check permission await ensureUserIsPermitted(currentUser, jobCandidateId) + // if M2M require hostUserId + if (currentUser.isMachine) { + const hostUserIdValidator = Joi.string().uuid().required() + const { error } = hostUserIdValidator.validate(interview.hostUserId) + if (error) { + throw new errors.BadRequestError(`interview.hostUserId ${interview.hostUserId} is required and must be a valid uuid`) + } + } + // find the round count const round = await Interview.count({ where: { jobCandidateId } @@ -233,30 +261,81 @@ async function requestInterview (currentUser, jobCandidateId, interview) { throw new errors.ConflictError(`You've reached the maximum allowed number (${InterviewConstants.MaxAllowedCount}) of interviews for this candidate.`) } - // get job candidate user details - const jobCandidate = await models.JobCandidate.findById(jobCandidateId) - const jobCandidateUser = await helper.getUserById(jobCandidate.userId) - const jobCandidateMember = await helper.getUserByHandle(jobCandidateUser.handle) // pre-populate fields interview.id = uuid() + interview.expireTimestamp = moment().add(config.INTERVIEW_SCHEDULING_EXPIRE_TIME) + interview.jobCandidateId = jobCandidateId interview.round = round + 1 - interview.duration = InterviewConstants.XaiTemplate[interview.templateUrl] interview.createdBy = await helper.getUserId(currentUser.userId) - interview.guestEmails = [jobCandidateMember.email, ...interview.guestEmails] - // pre-populate hostName & guestNames - const hostMembers = await helper.getMemberDetailsByEmails([interview.hostEmail]) - const guestMembers = await helper.getMemberDetailsByEmails(interview.guestEmails) - interview.hostName = `${hostMembers[0].firstName} ${hostMembers[0].lastName}` - interview.guestNames = _.map(interview.guestEmails, (guestEmail) => { - var foundGuestMember = _.find(guestMembers, function (guestMember) { return guestEmail === guestMember.email }) - return (foundGuestMember !== undefined) ? `${foundGuestMember.firstName} ${foundGuestMember.lastName}` : guestEmail.split('@')[0] - }) + + if (_.isNil(interview.hostUserId) || interview.hostUserId === '') { + interview.hostUserId = interview.createdBy + } let entity let jobCandidateEntity + let calendar try { await sequelize.transaction(async (t) => { + // get calendar if exists, otherwise create a virtual one for the user + const existentCalendar = await UserMeetingSettings.getPrimaryNylasCalendarForUser(interview.hostUserId) + if (_.isNil(existentCalendar)) { + const { email, firstName, lastName } = await helper.getUserDetailsByUserUUID(interview.hostUserId) + const currentUserFullname = `${firstName} ${lastName}` + calendar = await createVirtualCalendarForUser(interview.hostUserId, email, currentUserFullname, interview.hostTimezone) + // make the new calendar primary + calendar.isPrimary = true + } else { + calendar = existentCalendar + } + + // if primary calendar doesn't have `calendarId` + if (!calendar.calendarId) { + throw errors.BadRequestError(`Cannot schedule interview using calendar "${calendar.email}" as it was not fully connected. Try waiting a couple of minutes, removing or reconnecting the calendar.`) + } + + // configure scheduling page + const jobCandidate = await models.JobCandidate.findById(interview.jobCandidateId) + const job = await jobCandidate.getJob() + const pageOptions = { + eventTitle: `Job Interview for "${job.title}"` + } + // create scheduling page on nylas + let schedulingPage + try { + schedulingPage = await createSchedulingPage(interview, calendar, pageOptions) + logger.debug(`requestInterview -> createSchedulingPage created: ${JSON.stringify(schedulingPage)}, using accessToken: "${calendar.accessToken}"`) + } catch (err) { + logger.error(`requestInterview -> createSchedulingPage failed: ${err.toString()}, using accessToken: "${calendar.accessToken}"`) + throw err + } + + // Link nylasPage to interview + interview.nylasPageId = schedulingPage.id + interview.nylasPageSlug = schedulingPage.slug + interview.nylasCalendarId = calendar.calendarId + + // status handling will be implemented in another challenge it seems, setting the default value + interview.status = InterviewConstants.Status.Scheduling + + try { + await UserMeetingSettingsService.syncUserMeetingsSettings( + currentUser, + { + id: interview.hostUserId, + // when scheduling a new interview we always set/update default available time and timezone + defaultAvailableTime: interview.availableTime, + defaultTimezone: interview.hostTimezone, + // don't add calendar if we use existent one + calendar: !existentCalendar ? calendar : undefined + }, + t + ) + } catch (err) { + logger.debug(`requestInterview -> syncUserMeetingsSettings ERROR: ${JSON.stringify(err)}`) + throw err + } // create the interview const created = await Interview.create(interview, { transaction: t }) entity = created.toJSON() @@ -288,11 +367,24 @@ requestInterview.schema = Joi.object().keys({ currentUser: Joi.object().required(), jobCandidateId: Joi.string().uuid().required(), interview: Joi.object().keys({ - calendarEventId: Joi.string().allow(null), - templateUrl: Joi.xaiTemplate().required(), - hostEmail: Joi.string().email().required(), - guestEmails: Joi.array().items(Joi.string().email()).default([]), - status: Joi.interviewStatus().default(InterviewConstants.Status.Scheduling) + duration: Joi.number().integer().positive().required(), + hostTimezone: Joi.string().required(), + hostUserId: Joi.string().uuid(), + expireTimestamp: Joi.date(), + availableTime: Joi.array().min(1).items( + Joi.object({ + days: Joi.array().max(7).items(Joi.string().valid( + InterviewConstants.Nylas.Days.Monday, + InterviewConstants.Nylas.Days.Tuesday, + InterviewConstants.Nylas.Days.Wednesday, + InterviewConstants.Nylas.Days.Thursday, + InterviewConstants.Nylas.Days.Friday, + InterviewConstants.Nylas.Days.Saturday, + InterviewConstants.Nylas.Days.Sunday)).required(), + end: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required(), + start: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required() + }) + ).required() }).required() }).required() @@ -305,6 +397,7 @@ requestInterview.schema = Joi.object().keys({ * @returns {Object} updated interview */ async function partiallyUpdateInterview (currentUser, interview, data) { + const oldInterviewValue = interview.toJSON() // only status can be updated for Completed interviews if (interview.status === InterviewConstants.Status.Completed) { const updatedFields = _.keys(data) @@ -322,6 +415,24 @@ async function partiallyUpdateInterview (currentUser, interview, data) { let entity try { await sequelize.transaction(async (t) => { + // check if "duration", "availableTime" or "hostTimezone" changed. In that case we need to keep nylas consistent + if (interview.duration !== data.duration || interview.availableTime !== data.availableTime || interview.hostTimezone !== data.hostTimezone) { + const settingsForCalendar = await UserMeetingSettings.findOne({ + where: { + nylasCalendars: { + [Op.contains]: [{ calendarId: interview.nylasCalendarId }] + } + } + }) + const nylasAccessToken = _.find(settingsForCalendar.nylasCalendars, { calendarId: interview.nylasCalendarId }).accessToken + + await patchSchedulingPage(interview.nylasPageId, nylasAccessToken, { + duration: interview.duration !== data.duration ? data.duration : null, + availableTime: interview.availableTime !== data.availableTime ? data.availableTime : null, + timezone: interview.hostTimezone !== data.hostTimezone ? data.hostTimezone : null + }) + } + const updated = await interview.update(data, { transaction: t }) entity = updated.toJSON() await processUpdateInterview(entity) @@ -335,7 +446,7 @@ async function partiallyUpdateInterview (currentUser, interview, data) { // if reaches here, it's not one of the common errors handled in `handleSequelizeError` throw err } - await helper.postEvent(config.TAAS_INTERVIEW_UPDATE_TOPIC, entity, { oldValue: interview.toJSON() }) + await helper.postEvent(config.TAAS_INTERVIEW_UPDATE_TOPIC, entity, { oldValue: oldInterviewValue }) return entity } @@ -368,33 +479,35 @@ partiallyUpdateInterviewByRound.schema = Joi.object().keys({ jobCandidateId: Joi.string().uuid().required(), round: Joi.number().integer().positive().required(), data: Joi.object().keys({ - xaiId: Joi.string().allow(null), - calendarEventId: Joi.string().when('status', { - is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], - then: Joi.required(), - otherwise: Joi.allow(null) - }), - templateUrl: Joi.xaiTemplate(), - templateId: Joi.string().allow(null), - templateType: Joi.string().allow(null), - title: Joi.string().allow(null), - locationDetails: Joi.string().allow(null), + duration: Joi.number().integer().positive(), + hostTimezone: Joi.string(), + hostUserId: Joi.string().uuid(), + expireTimestamp: Joi.date(), + availableTime: Joi.array().min(1).items( + Joi.object({ + days: Joi.array().max(7).items(Joi.string().valid( + InterviewConstants.Nylas.Days.Monday, + InterviewConstants.Nylas.Days.Tuesday, + InterviewConstants.Nylas.Days.Wednesday, + InterviewConstants.Nylas.Days.Thursday, + InterviewConstants.Nylas.Days.Friday, + InterviewConstants.Nylas.Days.Saturday, + InterviewConstants.Nylas.Days.Sunday)).required(), + end: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required(), + start: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required() + }) + ), startTimestamp: Joi.date().greater('now').when('status', { is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], - then: Joi.required(), + then: Joi.invalid(null), otherwise: Joi.allow(null) }), endTimestamp: Joi.date().greater(Joi.ref('startTimestamp')).when('status', { is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], - then: Joi.required(), + then: Joi.invalid(null), otherwise: Joi.allow(null) }), - hostName: Joi.string(), - hostEmail: Joi.string().email(), - guestNames: Joi.array().items(Joi.string()).allow(null), - guestEmails: Joi.array().items(Joi.string().email()).allow(null), status: Joi.interviewStatus(), - rescheduleUrl: Joi.string().allow(null), deletedAt: Joi.date().allow(null) }).required().min(1) // at least one key - i.e. don't allow empty object }).required() @@ -402,74 +515,79 @@ partiallyUpdateInterviewByRound.schema = Joi.object().keys({ /** * Patch (partially update) interview by id * @param {Object} currentUser the user who perform this operation - * @param {String} id the interview or x.ai meeting id + * @param {String} id the interview * @param {Object} data object containing patched fields * @returns {Object} the patched interview object */ async function partiallyUpdateInterviewById (currentUser, id, data) { - var interview - if (uuidValidate(id)) { - interview = await Interview.findOne({ - where: { - [Op.or]: [ - { id } - ] - } - }) - } else { - interview = await Interview.findOne({ - where: { - [Op.or]: [ - { xaiId: id } - ] - } - }) - } - // throw NotFound error if doesn't exist - if (!!interview !== true) { - throw new errors.NotFoundError(`Interview doesn't exist with id/xaiId: ${id}`) - } - // check permission - await ensureUserIsPermitted(currentUser, interview.jobCandidateId) - - return await partiallyUpdateInterview(currentUser, interview, data) + return internallyUpdateInterviewById(currentUser, id, data) } partiallyUpdateInterviewById.schema = Joi.object().keys({ currentUser: Joi.object().required(), id: Joi.string().required(), data: Joi.object().keys({ - xaiId: Joi.string().required(), - calendarEventId: Joi.string().when('status', { - is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], - then: Joi.required(), - otherwise: Joi.allow(null) - }), - templateUrl: Joi.xaiTemplate(), - templateId: Joi.string().allow(null), - templateType: Joi.string().allow(null), - title: Joi.string().allow(null), - locationDetails: Joi.string().allow(null), + duration: Joi.number().integer().positive(), + hostTimezone: Joi.string(), + hostUserId: Joi.string().uuid(), + expireTimestamp: Joi.date(), + availableTime: Joi.array().min(1).items( + Joi.object({ + days: Joi.array().max(7).items(Joi.string().valid( + InterviewConstants.Nylas.Days.Monday, + InterviewConstants.Nylas.Days.Tuesday, + InterviewConstants.Nylas.Days.Wednesday, + InterviewConstants.Nylas.Days.Thursday, + InterviewConstants.Nylas.Days.Friday, + InterviewConstants.Nylas.Days.Saturday, + InterviewConstants.Nylas.Days.Sunday)).required(), + end: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required(), + start: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required() + }) + ), startTimestamp: Joi.date().greater('now').when('status', { is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], - then: Joi.required(), + then: Joi.invalid(null), otherwise: Joi.allow(null) }), endTimestamp: Joi.date().greater(Joi.ref('startTimestamp')).when('status', { is: [InterviewConstants.Status.Scheduled, InterviewConstants.Status.Rescheduled], - then: Joi.required(), + then: Joi.invalid(null), otherwise: Joi.allow(null) }), - hostName: Joi.string(), - hostEmail: Joi.string().email(), - guestNames: Joi.array().items(Joi.string()).allow(null), - guestEmails: Joi.array().items(Joi.string().email()).allow(null), status: Joi.interviewStatus(), - rescheduleUrl: Joi.string().allow(null), deletedAt: Joi.date().allow(null) }).required().min(1) // at least one key - i.e. don't allow empty object }).required() +/** + * Patch (partially update) interview by id + * + * The same as `partiallyUpdateInterviewById` but without validation for internal usage. + * + * @param {Object} currentUser the user who perform this operation + * @param {String} id the interview + * @param {Object} data object containing patched fields + * @returns {Object} the patched interview object + */ +async function internallyUpdateInterviewById (currentUser, id, data) { + const interview = await Interview.findOne({ + where: { + [Op.or]: [ + { id } + ] + } + }) + // throw NotFound error if doesn't exist + if (!!interview !== true) { + throw new errors.NotFoundError(`Interview doesn't exist with id: ${id}`) + } + // check permission + await ensureUserIsPermitted(currentUser, interview.jobCandidateId) + + return await partiallyUpdateInterview(currentUser, interview, data) +} + /** * List interviews * @param {Object} currentUser the user who perform this operation. @@ -479,7 +597,7 @@ partiallyUpdateInterviewById.schema = Joi.object().keys({ */ async function searchInterviews (currentUser, jobCandidateId, criteria) { // check permission - await ensureUserIsPermitted(currentUser, jobCandidateId) + await ensureUserIsPermitted(currentUser, jobCandidateId, true) const { page, perPage } = criteria @@ -652,12 +770,174 @@ async function updateCompletedInterviews () { logger.info({ component: 'InterviewService', context: 'updateCompletedInterviews', message: `Completed running. Updated ${affectedCount} interviews.` }) } +/** + * Update interview using received webhook data + * + * This method would be always called when someone selects time for new interview using Nylas Page. + * This would NOT be called when make updates to the events or cancel them, only when we create event as per Nylas logic. + * + * @param {String} interviewId interview id + * @param {Object} webhookBody webhook body + * @returns nothing + */ +async function partiallyUpdateInterviewByWebhook (interviewId, authToken, webhookBody) { + // don't await for response to prevent gateway timeout because it might wait for mutex to release + // we use mutex here, otherwise we might update the same interview using `NylasWebhookService` + // and there maybe race condition when updating the same record + runExclusiveInterviewEventHandler(async () => { + logger.debug({ component: 'InterviewService', context: 'partiallyUpdateInterviewByWebhook', message: `Mutex: processing webhook for interview id "${interviewId}": ${JSON.stringify(webhookBody)}` }) + + // Verify the request to make sure it's actually from Nylas. + if (!verifyNylasWebhookRequest(authToken)) { + logger.error({ + component: 'InterviewService', + context: 'partiallyUpdateInterviewByWebhook', + message: `Failed to verify Nylas webhook request authToken: ${authToken}` + }) + + throw new errors.UnauthorizedError('Webhook request failed verification.') + } + + // this method is used by the Nylas webhooks, so use M2M user + const m2mUser = helper.getAuditM2Muser() + const { page: pageDetails, booking: bookingDetails } = webhookBody + const interviewStartTimeMoment = moment.unix(bookingDetails.start_time) + const interviewEndTimeMoment = moment.unix(bookingDetails.end_time) + + if (bookingDetails.is_confirmed) { + try { + // get the associated interview + const interview = await Interview.findById(interviewId) + + // Nylas might create multiple events for the same booking, so we have to only listen for the event inside calendar which was used for interview booking + if (interview.nylasCalendarId !== bookingDetails.calendar_id) { + logger.debug({ + component: 'InterviewService', + context: 'partiallyUpdateInterviewByWebhook', + message: `Skipping event "${bookingDetails.calendar_event_id}" for interview "${interviewId}" because event calendar "${bookingDetails.calendar_id}" doesn't match interview calendar "${interview.nylasCalendarId}".` + }) + return + } + + const userMeetingSettingsForCalendar = await UserMeetingSettings.findOne({ + where: { + nylasCalendars: { + [Op.contains]: [{ calendarId: bookingDetails.calendar_id }] + } + } + }) + + if (!userMeetingSettingsForCalendar) { + throw new errors.BadRequestError('Error getting UserMeetingSettings for the booking calendar id.') + } + + const accessToken = _.find(userMeetingSettingsForCalendar.nylasCalendars, { calendarId: bookingDetails.calendar_id }).accessToken + + // Interview cancel/reschedule links + const cancelInterviewLink = `${config.TAAS_APP_BASE_URL}/interview/${interviewId}/cancel` + const rescheduleInterviewLink = `${config.TAAS_APP_BASE_URL}/interview/${interviewId}/reschedule` + + // update events endpoint only takes stringified values for any key in metadata + const pageId = pageDetails && pageDetails.id ? pageDetails.id.toString() : '' + const pageSlug = (pageDetails && pageDetails.slug) || '' + const eventDescription = `\n\nTo make changes to this event, click the links below:\n\nReschedule: ${rescheduleInterviewLink}\nCancel: ${cancelInterviewLink}` + + const updateEventData = { + description: eventDescription, + metadata: { + interviewId, + pageId, + pageSlug + } + } + + // update the Nylas event to set custom metadata + await updateEvent(bookingDetails.calendar_event_id, updateEventData, accessToken) + + await internallyUpdateInterviewById( + m2mUser, + interviewId, + { + status: InterviewConstants.Status.Scheduled, + startTimestamp: interviewStartTimeMoment.toDate(), + endTimestamp: interviewEndTimeMoment.toDate(), + // additionally `nylasEventId` would be always set inside NylasWebhookService to make sure it always happens before cancelling + nylasEventId: bookingDetails.calendar_event_id, + nylasEventEditHash: bookingDetails.edit_hash, + guestTimezone: interview.guestTimezone || bookingDetails.recipient_tz + } + ) + + logger.debug({ + component: 'InterviewService', + context: 'partiallyUpdateInterviewByWebhook', + message: `Interview scheduled by event "${bookingDetails.calendar_event_id}" in calendar "${bookingDetails.calendar_id}" for account "${bookingDetails.account_id}" on ${interviewStartTimeMoment.format('MMM DD YYYY HH:mm')}` + }) + } catch (err) { + logger.logFullError(err, { component: 'InterviewService', context: 'partiallyUpdateInterviewByWebhook' }) + throw new errors.BadRequestError(`Could not update interview: ${err.message}`) + } + } + }).then(() => { + logger.debug({ + component: 'InterviewService', + context: 'partiallyUpdateInterviewByWebhook', + message: 'Mutex: released' + }) + }).catch((err) => { + logger.logFullError(`Mutex: error "${err.toString()}".`, { component: 'InterviewService', context: 'partiallyUpdateInterviewByWebhook' }) + }) +} +partiallyUpdateInterviewByWebhook.schema = Joi.object().keys({ + interviewId: Joi.string().uuid().required(), + authToken: Joi.string().required(), + webhookBody: Joi.object().invalid({}).required() +}).required() + +/** + * Get zoom link. + * + * @param {String} interviewId the interview id + * @param {Object} data the request query data + * @returns zoom link + */ +async function getZoomLink (interviewId, data) { + const { type, id } = helper.verifyZoomLinkToken(data.token) + if (data.type !== type || interviewId !== id) { + throw new errors.BadRequestError('Invalid type or id.') + } + const interview = await Interview.findById(interviewId) + + // check if the interview zoom link is not expired + const { Completed, Cancelled, Expired } = InterviewConstants.Status + if (_.includes([Completed, Cancelled, Expired], interview.status)) { + throw new errors.BadRequestError(`Zoom link is no longer available for this interview because the current status of the interview is "${interview.status}".`) + } + const zoomMeeting = await getZoomMeeting(interview.zoomAccountApiKey, interview.zoomMeetingId) + if (data.type === ZoomLinkType.HOST) { + return zoomMeeting.start_url + } else if (data.type === ZoomLinkType.GUEST) { + return zoomMeeting.join_url + } +} + +getZoomLink.schema = Joi.object().keys({ + interviewId: Joi.string().uuid().required(), + data: Joi.object().keys({ + type: Joi.string().valid(ZoomLinkType.HOST, ZoomLinkType.GUEST).required(), + token: Joi.string().required() + }).required() +}).required() + module.exports = { getInterviewByRound, getInterviewById, requestInterview, partiallyUpdateInterviewByRound, partiallyUpdateInterviewById, + internallyUpdateInterviewById, searchInterviews, - updateCompletedInterviews + updateCompletedInterviews, + partiallyUpdateInterviewByWebhook, + getZoomLink } diff --git a/src/services/JobCandidateService.js b/src/services/JobCandidateService.js index 59a2b4f5..3d2b8a31 100644 --- a/src/services/JobCandidateService.js +++ b/src/services/JobCandidateService.js @@ -420,10 +420,7 @@ async function downloadJobCandidateResume (currentUser, id) { data: { jobCandidateUserHandle: handle, jobName: job.title, - description: 'Client Viewed Resume', - notificationType: { - jobCandidateResumeViewed: true - } + applicationUrl: `${config.TAAS_APP_EARN_URL}?status=Active%20Gigs` } }) diff --git a/src/services/NotificationsSchedulerService.js b/src/services/NotificationsSchedulerService.js index 90a6b58f..920f56f2 100644 --- a/src/services/NotificationsSchedulerService.js +++ b/src/services/NotificationsSchedulerService.js @@ -4,6 +4,7 @@ const _ = require('lodash') const { Op } = require('sequelize') const moment = require('moment') +const momentTz = require('moment-timezone') const config = require('config') const models = require('../models') const Job = models.Job @@ -13,6 +14,8 @@ const ResourceBooking = models.ResourceBooking const helper = require('../common/helper') const constants = require('../../app-constants') const logger = require('../common/logger') +const { getAuditM2Muser } = require('../common/helper') +const interviewService = require('./InterviewService') const localLogger = { debug: (message, context) => logger.debug({ component: 'NotificationSchedulerService', context, message }), @@ -71,6 +74,32 @@ async function getUserWithId (userId) { return user } +/** + * Format Interview time according to timezone of host or guest + * + * @param {object} interview + * @param {object} options + * + * @returns Formatted time in specified user's timezone + */ +function formatInterviewTime (interview, options = { forInterviewHost: false, forInterviewGuest: false }) { + // using format as used in helper.formatDateTimeEDT function, this also shows the provided timezone + const INTERVIEW_START_TIME_FORMAT = 'MMM D, YYYY, HH:mm z' + + let startTime + if (interview.startTimestamp) { + if (options.forInterviewHost) { + startTime = momentTz(interview.startTimestamp).tz(interview.hostTimezone).format(INTERVIEW_START_TIME_FORMAT) + } else if (options.forInterviewGuest) { + startTime = momentTz(interview.startTimestamp).tz(interview.guestTimezone).format(INTERVIEW_START_TIME_FORMAT) + } + } else { + startTime = '' + } + + return startTime +} + /** * returns the data for the interview * @param interview the interview @@ -83,25 +112,32 @@ async function getDataForInterview (interview, jobCandidate, job) { job = job || await Job.findById(jobCandidate.jobId) + const hostUserDetails = await helper.getUserDetailsByUserUUID(interview.hostUserId) + const userDetails = await helper.getUserDetailsByUserUUID(jobCandidate.userId) const user = await getUserWithId(jobCandidate.userId) if (!user) { return null } const interviewLink = `${config.TAAS_APP_URL}/${job.projectId}/positions/${job.id}/candidates/interviews` - const guestName = _.isEmpty(interview.guestNames) ? '' : interview.guestNames[0] const startTime = interview.startTimestamp ? helper.formatDateTimeEDT(interview.startTimestamp) : '' const jobUrl = `${config.TAAS_APP_URL}/${job.projectId}/positions/${job.id}` + const applicationUrl = `${config.TAAS_APP_EARN_URL}?status=Active%20Gigs` return { jobTitle: job.title, - guestFullName: guestName, - hostFullName: interview.hostName, + guestFullName: userDetails.firstName + ' ' + userDetails.lastName, + guestEmail: userDetails.email, + hostEmail: hostUserDetails.email, + hostFullName: hostUserDetails.firstName + ' ' + hostUserDetails.lastName, candidateName: `${user.firstName} ${user.lastName}`, handle: user.handle, - attendees: interview.guestNames, startTime: startTime, duration: interview.duration, + interviewId: interview.id, + interviewRound: interview.round, interviewLink, + applicationUrl, jobUrl + } } @@ -174,11 +210,7 @@ async function sendCandidatesAvailableNotifications () { recipients: projectTeamRecipients, data: { teamName: project.name, - teamJobs, - notificationType: { - candidatesAvailableForReview: true - }, - description: 'Candidates are available for review' + teamJobs } }) @@ -243,16 +275,24 @@ async function sendInterviewComingUpNotifications () { const data = await getDataForInterview(interview) if (!data) { continue } - if (!_.isEmpty(interview.hostEmail)) { + const TIME_FORMAT = 'dddd MMM. Do, hh:mm a' + const hostZoomToken = helper.signZoomLink({ type: constants.ZoomLinkType.HOST, id: interview.id }) + const hostZoomLink = `${config.TAAS_API_BASE_URL}/getInterview/${interview.id}/zoom-link?type=${constants.ZoomLinkType.HOST}&token=${hostZoomToken}` + + const guestZoomToken = helper.signZoomLink({ type: constants.ZoomLinkType.GUEST, id: interview.id }) + const guestZoomLink = `${config.TAAS_API_BASE_URL}/getInterview/${interview.id}/zoom-link?type=${constants.ZoomLinkType.GUEST}&token=${guestZoomToken}` + if (!_.isEmpty(data.hostEmail)) { sendNotification({}, { template: 'taas.notification.interview-coming-up-host', - recipients: [{ email: interview.hostEmail }], + recipients: [{ email: data.hostEmail }], data: { - ...data, - notificationType: { - interviewComingUpForHost: true - }, - description: 'Interview Coming Up' + guest: data.guestFullName, + jobTitle: data.jobTitle, + zoomLink: hostZoomLink, + start: moment(interview.startTimestamp).tz(interview.hostTimezone).format(TIME_FORMAT) + ` ${interview.hostTimezone}`, + end: moment(interview.endTimestamp).tz(interview.hostTimezone).format(TIME_FORMAT) + ` ${interview.hostTimezone}`, + hostTimezone: interview.hostTimezone, + interviewLink: data.interviewLink } }) @@ -261,17 +301,20 @@ async function sendInterviewComingUpNotifications () { localLogger.error(`Interview id: ${interview.id} host email not present`, 'sendInterviewComingUpNotifications') } - if (!_.isEmpty(interview.guestEmails)) { + if (!_.isEmpty(data.guestEmail)) { + // fallback to host timezone if by some reason we didn't obtain guest timezone + const guestTimezone = interview.guestTimezone || interview.hostTimezone // send guest emails sendNotification({}, { template: 'taas.notification.interview-coming-up-guest', - recipients: interview.guestEmails.map((email) => ({ email })), + recipients: [{ email: data.guestEmail }], data: { - ...data, - notificationType: { - interviewComingUpForGuest: true - }, - description: 'Interview Coming Up' + host: data.hostFullName, + jobTitle: data.jobTitle, + zoomLink: guestZoomLink, + start: moment(interview.startTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + end: moment(interview.endTimestamp).tz(guestTimezone).format(TIME_FORMAT) + ` ${guestTimezone}`, + guestTimezone } }) @@ -331,28 +374,24 @@ async function sendInterviewCompletedNotifications () { let sentCount = 0 for (const interview of interviews) { - if (_.isEmpty(interview.hostEmail)) { - localLogger.error(`Interview id: ${interview.id} host email not present`) - continue - } if (!jcMap[interview.jobCandidateId] || jcMap[interview.jobCandidateId].status !== constants.JobCandidateStatus.INTERVIEW) { localLogger.error(`Interview id: ${interview.id} job candidate status is not ${constants.JobCandidateStatus.INTERVIEW}`) continue } const data = await getDataForInterview(interview, jcMap[interview.jobCandidateId]) + + if (_.isEmpty(data.hostEmail)) { + localLogger.error(`Interview id: ${interview.id} host email not present`) + continue + } if (!data) { continue } + data.startTime = formatInterviewTime(interview, { forInterviewHost: true }) sendNotification({}, { template: 'taas.notification.interview-awaits-resolution', - recipients: [{ email: interview.hostEmail }], - data: { - ...data, - notificationType: { - interviewCompleted: true - }, - description: 'Interview Completed' - } + recipients: [{ email: data.hostEmail }], + data }) sentCount++ @@ -423,6 +462,7 @@ async function sendPostInterviewActionNotifications () { const d = await getDataForInterview(interview, projectJc, projectJob) if (!d) { continue } d.jobUrl = `${config.TAAS_APP_URL}/${projectId}/positions/${projectJob.id}` + d.startTime = formatInterviewTime(interview, { forInterviewHost: true }) webNotifications.push({ serviceId: 'web', type: template, @@ -449,11 +489,7 @@ async function sendPostInterviewActionNotifications () { data: { teamName: project.name, numCandidates, - teamInterviews, - notificationType: { - postInterviewCandidateAction: true - }, - description: 'Post Interview Candidate Action Reminder' + teamInterviews } }, webNotifications) @@ -552,11 +588,7 @@ async function sendResourceBookingExpirationNotifications () { teamName: project.name, numResourceBookings, teamResourceBookings, - notificationType: { - upcomingResourceBookingExpiration: true - }, - teamUrl, - description: 'Upcoming Resource Booking Expiration' + teamUrl } }, [webData]) @@ -609,11 +641,183 @@ async function sendNotification (currentUser, data, webNotifications = []) { }) } +// Send notifications to job candicate for time selection reminder +async function sendInterviewScheduleReminderNotifications () { + const INTERVIEW_REMINDER_DAY_AFTER = config.get('INTERVIEW_REMINDER_DAY_AFTER') + const INTERVIEW_REMINDER_FREQUENCY = config.get('INTERVIEW_REMINDER_FREQUENCY') + + localLogger.debug('[sendInterviewScheduleReminderNotifications]: Looking for due records...') + const currentTime = moment.utc() + const compareTime = currentTime.clone().subtract(moment.duration(INTERVIEW_REMINDER_DAY_AFTER)).endOf('day') + + const timestampFilter = { + [Op.and]: [ + { + [Op.lte]: compareTime + } + ] + } + + const filter = { + [Op.and]: [ + { + status: { + [Op.in]: [ + constants.Interviews.Status.Scheduling + ] + } + }, + { + createdAt: timestampFilter + } + ] + } + + const interviews = await Interview.findAll({ + where: filter, + raw: true + }) + + const template = 'taas.notification.interview-schedule-reminder' + + let interviewCount = 0 + for (const interview of interviews) { + const start = moment(interview.createdAt) + if (currentTime.clone().subtract(INTERVIEW_REMINDER_DAY_AFTER).diff(start, 'days') % INTERVIEW_REMINDER_FREQUENCY === 0) { + const minutesInterval = currentTime.clone().diff(start, 'minutes') % (60 * 24) + if (minutesInterval < moment.duration(config.INTERVIEW_SCHEDULE_REMINDER_WINDOW).minutes()) { + // sendEmail + const data = await getDataForInterview(interview) + if (!data) { continue } + + if (!_.isEmpty(data.guestEmail)) { + // send guest emails + sendNotification({}, { + template, + recipients: [{ email: data.guestEmail }], + data: { + ...data, + subject: `Reminder: ${data.duration} minutes tech interview with ${data.guestFullName} for ${data.jobTitle} is requested by the Customer` + } + }) + } else { + localLogger.error(`Interview id: ${interview.id} guest emails not present`, 'sendInterviewScheduleReminderNotifications') + } + interviewCount++ + } + } + } + + localLogger.debug(`[sendInterviewScheduleReminderNotifications]: Sent notifications for ${interviewCount} interviews which need to schedule.`) +} + +// Send notifications to customer and candidate this interview has expired +async function sendInterviewExpiredNotifications () { + localLogger.debug('[sendInterviewExpiredNotifications]: Looking for due records...') + const currentTime = moment.utc().startOf('minute') + + const timestampFilter = { + [Op.and]: [ + { + [Op.lte]: currentTime + } + ] + } + + const filter = { + [Op.and]: [ + { + status: { + [Op.in]: [ + constants.Interviews.Status.Scheduling + ] + } + }, + { + expireTimestamp: timestampFilter + } + ] + } + + const interviews = await Interview.findAll({ + where: filter, + raw: true + }) + + localLogger.debug(`[sendInterviewExpiredNotifications]: Found ${interviews.length} interviews which are expired.`) + + const templateHost = 'taas.notification.interview-expired-host' + const templateGuest = 'taas.notification.interview-expired-guest' + + for (const interview of interviews) { + // this method is run by the app itself + const m2mUser = getAuditM2Muser() + + await interviewService.partiallyUpdateInterviewById( + m2mUser, + interview.id, + { + status: constants.Interviews.Status.Expired + } + ) + + // send host email + const data = await getDataForInterview(interview) + if (!data) { continue } + + if (!_.isEmpty(data.hostEmail)) { + sendNotification({}, { + template: templateHost, + recipients: [{ email: data.hostEmail }], + data: { + ...data, + subject: `Candidate Didn't Schedule Interview: ${data.duration} minutes tech interview with ${data.guestFullName} for ${data.jobTitle} is requested by the Customer` + } + }) + } else { + localLogger.error(`Interview id: ${interview.id} host email not present`, 'sendInterviewExpiredNotifications') + } + + if (!_.isEmpty(data.guestEmail)) { + // send guest emails + sendNotification({}, { + template: templateGuest, + recipients: [{ email: data.guestEmail }], + data: { + ...data, + subject: `Interview Invitation Expired: ${data.duration} minutes tech interview with ${data.guestFullName} for ${data.jobTitle} is requested by the Customer` + } + }) + } else { + localLogger.error(`Interview id: ${interview.id} guest emails not present`, 'sendInterviewExpiredNotifications') + } + } + + localLogger.debug(`[sendInterviewExpiredNotifications]: Sent notifications for ${interviews.length} interviews which are expired.`) +} + +/** + * For preventing app crashing by scheduler function, use this function to wrapper target handler. + * @param {*} callback : function handler + */ +function errorCatchWrapper (callback, name) { + return async () => { + try { + await callback() + } catch (e) { + localLogger.error(`${[name]} Service function error: ${e}`) + } + } +} + module.exports = { sendNotification, - sendCandidatesAvailableNotifications, - sendInterviewComingUpNotifications, - sendInterviewCompletedNotifications, - sendPostInterviewActionNotifications, - sendResourceBookingExpirationNotifications + sendCandidatesAvailableNotifications: errorCatchWrapper(sendCandidatesAvailableNotifications, 'sendCandidatesAvailableNotifications'), + sendInterviewComingUpNotifications: errorCatchWrapper(sendInterviewComingUpNotifications, 'sendInterviewComingUpNotifications'), + sendInterviewCompletedNotifications: errorCatchWrapper(sendInterviewCompletedNotifications, 'sendInterviewCompletedNotifications'), + sendInterviewExpiredNotifications: errorCatchWrapper(sendInterviewExpiredNotifications, 'sendInterviewExpiredNotifications'), + sendInterviewScheduleReminderNotifications: errorCatchWrapper(sendInterviewScheduleReminderNotifications, 'sendInterviewScheduleReminderNotifications'), + getDataForInterview, + sendPostInterviewActionNotifications: errorCatchWrapper(sendPostInterviewActionNotifications, 'sendPostInterviewActionNotifications'), + sendResourceBookingExpirationNotifications: errorCatchWrapper(sendResourceBookingExpirationNotifications, 'sendResourceBookingExpirationNotifications') } diff --git a/src/services/NylasService.js b/src/services/NylasService.js new file mode 100644 index 00000000..c4196b4f --- /dev/null +++ b/src/services/NylasService.js @@ -0,0 +1,335 @@ +/** + * This service provides operations to interact with Nylas API + */ + +const axios = require('axios') +const { createHash } = require('crypto') +const config = require('config') +const _ = require('lodash') +const { v4: uuid } = require('uuid') + +/** + * @param {Object} calendarName the name of the Nylas calendar + * @param {Object} hostTimezone the timezone of the event + * @param {Object} accessToken the accessToken to authenticate with Nylas + * @returns {Object} the created calendar + */ +async function createVirtualCalendar (calendarName, hostTimezone, accessToken) { + const res = await axios.post('https://api.nylas.com/calendars', { + name: calendarName, + description: 'Virtual Calendar', + timezone: hostTimezone + }, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + return res.data +} + +/** + * @param {Object} userId id of the user + * @param {Object} userEmail email of the user + * @param {Object} userFullName fullname of the user + * @param {Object} timezone the timezone of the event + * @returns {String} id of the created virtual calendar + */ +async function createVirtualCalendarForUser (userId, userEmail, userFullName, timezone) { + // We don't use email directly to identify user virtual calendar, because of the bug in Nylas + // If user connects Google/Microsoft calendar using the same email, + // then we always get Google/Microsoft account instead of nylas account + // so to bypass it, instead of email we use email with prefix, so Nylas Virtual Calendar email + // would never match real user email which they connect to Google/Microsoft + const virtualCalendarEmail = `virtual-calendar:${userEmail}` + const code = await authenticateAccount(userFullName, virtualCalendarEmail) + const { accessToken, provider } = await getAccessToken(code) + + let calendar = await getPrimaryCalendar(accessToken) + + // if don't have existent calendar, then create a new one + if (!calendar) { + try { + calendar = await createVirtualCalendar(userFullName, timezone, accessToken) + } catch (err) { + throw new Error(`Could not create a virtual calendar because of error: ${JSON.stringify(err)}`) + } + } + + return { + id: uuid(), // internal UUID + calendarId: calendar.id, + accountId: calendar.account_id, + accessToken, + accountProvider: provider, + email: userEmail, + isPrimary: calendar.is_primary, + isDeleted: false + } +} + +async function getExistingCalendars (accessToken) { + const res = await axios.get('https://api.nylas.com/calendars', { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + + return res.data +} + +async function getAccountEmail (accountId) { + const base64Secret = Buffer.from( + `${config.get('NYLAS_CLIENT_SECRET')}:` + ).toString('base64') + const res = await axios.get( + `https://api.nylas.com/a/${config.get( + 'NYLAS_CLIENT_ID' + )}/accounts/${accountId}`, + { + headers: { + Authorization: `Basic ${base64Secret}` + } + } + ) + + return res.data.email +} + +async function authenticateAccount (userFullName, email) { + const res = await axios.post('https://api.nylas.com/connect/authorize', { + client_id: config.NYLAS_CLIENT_ID, + provider: 'nylas', + scopes: 'calendar', + email, + name: userFullName, + settings: {} + }) + + return res.data.code +} + +async function getAccessToken (code) { + const res = await axios.post('https://api.nylas.com/connect/token', { + client_id: config.NYLAS_CLIENT_ID, + client_secret: config.NYLAS_CLIENT_SECRET, + code + }) + + const { account_id: accountId, access_token: accessToken, provider, email_address: email } = res.data + + return { accountId, accessToken, provider, email } +} + +async function getEvent (accountId, eventId) { + const email = await getAccountEmail(accountId) + const code = await authenticateAccount('', email) + const { accessToken } = await getAccessToken(code) + + try { + const res = await axios.get(`https://api.nylas.com/events/${eventId}`, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + + return res.data + } catch (err) { + const customError = new Error(`Error getting event "${eventId}": ${err.toString()}`) + // we must return http status of error as we are relying on it + customError.httpStatus = _.get(err, 'response.status') + throw customError + } +} + +/** + * Get Nylas calendar + * + * @param {String} calendarId calendar id + * @param {String} accessToken Nylas account access token + * @returns {Promise} Nylas calendar + */ +async function getCalendar (calendarId, accessToken) { + try { + const res = await axios.get(`https://api.nylas.com/calendars/${calendarId}`, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + + return res.data + } catch (err) { + throw new Error(`Error getting calendar "${calendarId}": ${err.toString()}`) + } +} + +function getAvailableTimeFromSchedulingPage (page) { + return page.config.booking.opening_hours +} +function getTimezoneFromSchedulingPage (page) { + return page.config.timezone +} + +async function createSchedulingPage (interview, calendar, options) { + const webhookAuthTokenSecret = config.NYLAS_SCHEDULER_WEBHOOK_SECRET + const authTokenHash = createHash('sha256') + .update(webhookAuthTokenSecret) + .digest('hex') + + const res = await axios.post('https://api.schedule.nylas.com/manage/pages', { + access_tokens: [calendar.accessToken], + slug: `tc-taas-interview-${interview.id}`, + config: { + appearance: { + thank_you_redirect: `${config.TAAS_APP_BFF_BASE_URL}/misc/interview-thank-you-page`, + show_autoschedule: false // Hides the Google / Outlook connect buttons in scheduling page + }, + booking: { + additional_guests_hidden: true, + available_days_in_future: config.INTERVIEW_AVAILABLE_DAYS_IN_FEATURE, + opening_hours: [].concat(interview.availableTime), + // don't send confirmation emails using Nylas, as we are sending custom emails from TaaS + confirmation_emails_to_guests: false, + confirmation_emails_to_host: false + }, + calendar_ids: { + [calendar.accountId]: { + availability: [calendar.calendarId], + booking: calendar.calendarId + } + }, + event: { + duration: interview.duration, // default duration. + title: options.eventTitle // becomes the title of the Edit availability modal, unless overridden through UI + }, + expire_after: { + date: interview.expireTimestamp.unix() + }, + reminders: [ + { + delivery_method: 'webhook', + delivery_recipient: 'owner', + // This time needs to be greater than the furthest out an event can be scheduled in minutes. + time_before_event: config.INTERVIEW_AVAILABLE_DAYS_IN_FEATURE * 24 * 60 + 1, + webhook_url: `${config.NYLAS_SCHEDULER_WEBHOOK_BASE_URL}/updateInterview/${interview.id}/nylas-webhooks?authToken=${authTokenHash}` + } + ], + timezone: interview.hostTimezone + }, + disableViewingPages: true + }) + + return res.data +} + +async function patchSchedulingPage (pageId, accessToken, changes) { + const page = await axios.get(`https://api.schedule.nylas.com/manage/pages/${pageId}`, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + + let dirty = false + const updatedPage = page.data + if (!_.isNil(changes.duration)) { + _.set(updatedPage, 'config.event.duration', changes.duration) + dirty = true + } + if (!_.isNil(changes.availableTime)) { + _.set(updatedPage, 'config.booking.opening_hours', [].concat(changes.availableTime)) + dirty = true + } + if (!_.isNil(changes.timezone)) { + _.set(updatedPage, 'config.timezone', changes.timezone) + dirty = true + } + + if (dirty) { + const res = await axios.put(`https://api.schedule.nylas.com/manage/pages/${pageId}`, updatedPage, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + return res.data + } + // no changes + return page +} + +/** + * Detect calendar which would be used as a primary one + * + * @param {Array} calendars list of Nylas calendars + * @returns + */ +async function findPrimaryCalendar (calendars) { + const primaryCalendar = _.find(calendars, { is_primary: true, read_only: false }) + + if (primaryCalendar) { + return primaryCalendar + } + + const writableCalendars = _.filter(calendars, { read_only: false }) + + if (writableCalendars.length > 0) { + return writableCalendars[0] + } + + return null +} + +/** + * Update the Nylas event with provided data + * + * @param {string} eventId + * @param {object} data - this endpoint only takes stringified values for any key in metadata + * @returns {object} the updated event record + */ +async function updateEvent (eventId, data, accessToken) { + try { + const res = await axios.put(`https://api.nylas.com/events/${eventId}`, data, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + return res.data + } catch (err) { + throw new Error(`Error updating event "${eventId}" with data "${JSON.stringify(data)}": ${err.toString()}`) + } +} + +/** + * Load calendars from Nylas and return the primary writable calendar + * + * @param {String} accessToken Nylas access token + * @returns {Object} calendar + */ +async function getPrimaryCalendar (accessToken) { + // getting user's all existing calendars + const calendars = await getExistingCalendars(accessToken) + if (!Array.isArray(calendars) || calendars.length < 1) { + return null + } + + const primaryCalendar = await findPrimaryCalendar(calendars) + if (!primaryCalendar) { + return null + } + + return primaryCalendar +} + +module.exports = { + createVirtualCalendarForUser, + createSchedulingPage, + patchSchedulingPage, + getAvailableTimeFromSchedulingPage, + getTimezoneFromSchedulingPage, + getAccessToken, + getEvent, + getCalendar, + getPrimaryCalendar, + findPrimaryCalendar, + getAccountEmail, + updateEvent, + authenticateAccount +} diff --git a/src/services/NylasWebhookService.js b/src/services/NylasWebhookService.js new file mode 100644 index 00000000..7e804be2 --- /dev/null +++ b/src/services/NylasWebhookService.js @@ -0,0 +1,373 @@ +const config = require('config') +const { Interviews: { Status: InterviewStatus } } = require('../../app-constants') + +const crypto = require('crypto') +const _ = require('lodash') +const moment = require('moment') +const { validate: uuidValidate } = require('uuid') +const { Op } = require('sequelize') + +const logger = require('../common/logger') +const InterviewService = require('./InterviewService') +const NylasService = require('./NylasService') +const UserMeetingSettingsService = require('./UserMeetingSettingsService') +const { Interview, UserMeetingSettings } = require('../../src/models') +const helper = require('../common/helper') +const errors = require('../common/errors') + +const localLogger = { + debug: (message, context) => + logger.debug({ component: 'NylasWebhookService', context, message }), + error: (message, context) => + logger.error({ component: 'NylasWebhookService', context, message }), + info: (message, context) => + logger.info({ component: 'NylasWebhookService', context, message }) +} + +const EVENT_TYPE = { + EVENT: { + CREATED: 'event.created', + UPDATED: 'event.updated', + DELETED: 'event.deleted' + }, + CALENDAR: { + CREATED: 'calendar.created', + UPDATED: 'calendar.updated', + DELETED: 'calendar.deleted' + } +} + +const eventProcessors = { + [EVENT_TYPE.EVENT.CREATED]: processEventCreatedWebhook, + [EVENT_TYPE.EVENT.UPDATED]: processEventUpdatedWebhook, + [EVENT_TYPE.CALENDAR.CREATED]: processCalendarCreatedWebhook +} + +const getInterviewIdFromEvent = (event) => { + // if we already update event description and added metadata, then use it to get interview id + if (_.get(event, 'metadata.interviewId')) { + return event.metadata.interviewId + } + + if (!event.description) { + throw new Error(`Cannot get interview id for event ${event.id} as it doesn't have description.`) + } + + // if this is a new event and we haven't updated description yet, and haven't set metadata, + // then parse description + const matchIdOriginalDescription = event.description.match(/tc-taas-interview-([^/]+)/) + const interviewIdFromOriginalDescription = matchIdOriginalDescription && matchIdOriginalDescription[1] + if (uuidValidate(interviewIdFromOriginalDescription)) { + return interviewIdFromOriginalDescription + } + + // if this is a duplicate event which we are actually not interested in, then it would have update description, but not updated metadata + // so we extract id from the updated description + const matchIdUpdatedDescription = event.description.match(/taas\/interview\/([^/]+)/) + const interviewIdFromUpdatedDescription = matchIdUpdatedDescription && matchIdUpdatedDescription[1] + if (uuidValidate(interviewIdFromUpdatedDescription)) { + return interviewIdFromUpdatedDescription + } + + throw new Error(`Cannot get interview id for event ${event.id}.`) +} + +/** + * Process "event.created" webhook + * + * - associate created event with interview + * + * @param {Object} webhookData webhook data + * @param {Number} webhookId webhook id for tracking + */ +async function processEventCreatedWebhook (webhookData, webhookId) { + // start retrieving event immediately after getting webhook + // but don't wait for it, the main code should be run inside mutex + // to process all the webhooks in correct order + const eventPromise = NylasService.getEvent( + webhookData.object_data.account_id, + webhookData.object_data.id + ).then((event) => { + localLogger.debug(`Got object details for webhook, type: ${webhookData.type}, status: ${event.status}, id: ${event.id}, event: ${JSON.stringify(event)}`, `processEventCreatedWebhook #webhook-${webhookId}`) + + return event + }).catch((err) => { + localLogger.error(err, `processEventCreatedWebhook #webhook-${webhookId}`) + + return null + }) + // we have to use mutex here to support re-scheduling + // otherwise when new event is created we might not yet update `nylasEventId` + // and then we would accidentally cancel re-scheduled event + await helper.runExclusiveInterviewEventHandler(async () => { + localLogger.debug(`Mutex: acquired. Webhook type: "${webhookData.type}", object id: "${webhookData.object_data.id}", date: "${moment.unix(webhookData.date).utc().format()}"`, `processEventCreatedWebhook #webhook-${webhookId}`) + try { + const event = await eventPromise + + if (!event) { + throw new errors.BadRequestError(`Could not get event "${webhookData.object_data.id}".`) + } + + let interviewId + try { + interviewId = getInterviewIdFromEvent(event) + } catch (err) { + localLogger.debug(`Ignoring event "${event.id}" because cannot extract interview id from its description "${event.description}".`, `processEventCreatedWebhook #webhook-${webhookId}`) + return + } + + if (event.status === 'confirmed') { + const interview = await Interview.findById(interviewId) + if (!interview) { + throw new errors.BadRequestError(`Could not find interview with given id: ${interviewId}`) + } + + // Nylas might create multiple events for the same booking, so we have to only listen for the event inside calendar which was used for interview booking + if (interview.nylasCalendarId !== event.calendar_id) { + localLogger.debug(`Ignoring event "${event.id}" for interview "${interviewId}" because event calendar "${event.calendar_id}" doesn't match interview calendar "${interview.nylasCalendarId}".`, `processEventCreatedWebhook #webhook-${webhookId}`) + return + } + + // this method is used by the Nylas webhooks, so use M2M user + const m2mUser = helper.getAuditM2Muser() + + await InterviewService.internallyUpdateInterviewById( + m2mUser, + interviewId, + { + nylasEventId: event.id + // other fields would be updated inside `partiallyUpdateInterviewByWebhook` + } + ) + + if (interview.nylasEventId) { + localLogger.debug(`Interview with id "${interview.id}" has been re-assigned from Nylas event id "${interview.nylasEventId}" to "${event.id}".`, `processEventCreatedWebhook #webhook-${webhookId}`) + } else { + localLogger.debug(`Interview with id "${interview.id}" is now assigned to Nylas event id "${event.id}".`, `processEventCreatedWebhook #webhook-${webhookId}`) + } + } else { + localLogger.debug(`ignoring event, type: ${webhookData.type}, status: ${event.status}, id: ${event.id}`, `processEventCreatedWebhook #webhook-${webhookId}`) + } + } catch (err) { + localLogger.error(err, `processEventCreatedWebhook #webhook-${webhookId}`) + } + }).then(() => { + localLogger.debug('Mutex: released.', `processEventCreatedWebhook #webhook-${webhookId}`) + }).catch((err) => { + localLogger.error(`Mutex: error "${err.toString()}".`, `processEventCreatedWebhook #webhook-${webhookId}`) + }) +} + +/** + * Process "event.updated" webhook + * + * - marks interview as cancelled when associated event is cancelled + * + * @param {Object} webhookData webhook data + * @param {Number} webhookId webhook id for tracking + */ +async function processEventUpdatedWebhook (webhookData, webhookId) { + const eventId = webhookData.object_data.id + // start retrieving event immediately after getting webhook + // but don't wait for it, the main code should be run inside mutex + // to process all the webhooks in correct order + const eventStatusPromise = NylasService.getEvent( + webhookData.object_data.account_id, + webhookData.object_data.id + ).then((event) => { + localLogger.debug(`Got object details for webhook, type: ${webhookData.type}, status: ${event.status}, id: ${event.id}, event: ${JSON.stringify(event)}`, `processEventUpdatedWebhook #webhook-${webhookId}`) + + // if we could get the event, then just return its status + return event.status + }).catch((err) => { + // if we cannot load event from Nylas it means Nylas internally has deleted it + // so we can treat this case as "cancelled" if previously it was us who created such an event + if (err.httpStatus === 404) { + return 'deleted' + } + + localLogger.error(err, `processEventUpdatedWebhook #webhook-${webhookId}`) + return null + }) + // we have to use mutex here to support re-scheduling + // otherwise when new event is created we might not yet update `nylasEventId` + // and then we would accidentally cancel re-scheduled event + await helper.runExclusiveInterviewEventHandler(async () => { + localLogger.debug(`Mutex: acquired. Webhook type: "${webhookData.type}", object id: "${webhookData.object_data.id}", date: "${moment.unix(webhookData.date).utc().format()}"`, `processEventUpdatedWebhook #webhook-${webhookId}`) + try { + const eventStatus = await eventStatusPromise + + if (!eventStatus) { + throw new errors.BadRequestError(`Could not determine event status for "${eventId}".`) + } + + if (eventStatus === 'cancelled' || eventStatus === 'deleted') { + // find interview associated with this event + let interview + try { + interview = await Interview.findByNylasEventId(eventId) + localLogger.debug(`Found interview "${interview.id}" associated with event "${eventId}".`, `processEventUpdatedWebhook #webhook-${webhookId}`) + } catch (err) { + localLogger.debug(`Ignoring event "${eventId}" because cannot find any interview associated with this event.`, `processEventUpdatedWebhook #webhook-${webhookId}`) + return + } + + if (interview.status === InterviewStatus.Cancelled) { + localLogger.debug(`Ignoring event "${eventId}" for interview "${interview.id}" because this interview is already cancelled.`, `processEventUpdatedWebhook #webhook-${webhookId}`) + return + } + + // this method is used by the Nylas webhooks, so use M2M user + const m2mUser = helper.getAuditM2Muser() + + await InterviewService.internallyUpdateInterviewById( + m2mUser, + interview.id, + { + status: InterviewStatus.Cancelled + } + ) + + localLogger.debug(`Interview "${interview.id}" was canceled by webhook by "${eventStatus}" event "${eventId}".`, `processEventUpdatedWebhook #webhook-${webhookId}`) + } else { + localLogger.debug(`Ignoring event ${eventId}, status "${eventStatus}", type: ${webhookData.type}`, `processEventUpdatedWebhook #webhook-${webhookId}`) + } + } catch (err) { + localLogger.error(err, `processEventUpdatedWebhook #webhook-${webhookId}`) + } + }).then(() => { + localLogger.debug('Mutex: released.', `processEventCreatedWebhook #webhook-${webhookId}`) + }).catch((err) => { + localLogger.error(`Mutex: error "${err.toString()}".`, `processEventCreatedWebhook #webhook-${webhookId}`) + }) +} + +/** + * Process "calendar.created" webhook + * + * - save calendar id for created calendar if it wasn't saved before + * + * @param {Object} webhookData webhook data + * @param {Number} webhookId webhook id for tracking + */ +async function processCalendarCreatedWebhook (webhookData, webhookId) { + // wait for the end of `UserMeetingSettingsService.handleConnectCalendarCallback` is it's currently running + await helper.waitForUnlockCalendarConnectionHandler(async () => { + localLogger.debug(`Interview mutex unlocked. Processing webhook type: "${webhookData.type}", object id: "${webhookData.object_data.id}", date: "${moment.unix(webhookData.date).utc().format()}"`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + + // as multiple calendars could come during short period of time + // to keep the logic more predictable we process calendars one by one for the same account using mutex + const mutexName = `mutex-webhook-calendar-for-account-${webhookData.object_data.account_id}` + await helper.runExclusiveByNamedMutex(mutexName, async () => { + localLogger.debug(`#${mutexName} Mutex: acquired. Processing webhook type: "${webhookData.type}", object id: "${webhookData.object_data.id}", date: "${moment.unix(webhookData.date).utc().format()}"`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + const userMeetingSettingsForCalendar = await UserMeetingSettings.findOne({ + where: { + nylasCalendars: { + [Op.contains]: [{ accountId: webhookData.object_data.account_id }] + } + } + }) + + if (!userMeetingSettingsForCalendar) { + localLogger.debug(`Ignoring created calendar "${webhookData.object_data.id}" because there are no users who connected calendar with Nylas Account Id: "${webhookData.object_data.account_id}".`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + return + } + + localLogger.debug(`Found user settings associated with created calendar: ${JSON.stringify(userMeetingSettingsForCalendar)}`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + + const calendarRecord = _.find(userMeetingSettingsForCalendar.nylasCalendars, { accountId: webhookData.object_data.account_id }) + + if (calendarRecord.calendarId) { + localLogger.debug(`Ignoring created calendar "${webhookData.object_data.id}" because user already has calendar "${calendarRecord.calendarId}" for account "${calendarRecord.accountId}" email "${calendarRecord.email}".`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + return + } + + const accessToken = calendarRecord.accessToken + + const calendar = await NylasService.getCalendar(webhookData.object_data.id, accessToken) + + localLogger.debug(`Got object details for webhook, type: ${webhookData.type}, id: ${calendar.id}, calendar: ${JSON.stringify(calendar)}`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + + // check if loaded calendar could play role of a primary calendar + const canBePrimary = !!(await NylasService.findPrimaryCalendar([calendar])) + if (!canBePrimary) { + localLogger.debug(`Ignoring read-only calendar "${webhookData.object_data.id}" for account "${calendarRecord.accountId}" email "${calendarRecord.email}".`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + return + } + + // NOTE, that we cannot use `userId` because it's UUID, while in + // `currentUser` we need to have integer user id + const user = _.pick(await helper.getUserDetailsByUserUUID(userMeetingSettingsForCalendar.id), ['userId', 'handle']) + + await UserMeetingSettingsService.syncUserMeetingsSettings(user, { + id: userMeetingSettingsForCalendar.id, + calendar: { + ...calendarRecord, + calendarId: calendar.id // we are only setting calendar id + } + }) + + localLogger.debug(`Linked user settings "${userMeetingSettingsForCalendar.id}" account "${calendarRecord.accountId}" email "${calendarRecord.email}" with calendar "${calendar.id}".`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + }).then(() => { + localLogger.debug(`#${mutexName} Mutex: released.`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + }).catch((err) => { + localLogger.error(`#${mutexName} Mutex: error. "${err.toString()}".`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + }) + }).catch((err) => { + localLogger.error(`Error "${err.toString()}".`, `processCalendarCreatedWebhook #webhook-${webhookId}`) + }) +} + +// Each request made by Nylas includes an X-Nylas-Signature header. The header +// contains the HMAC-SHA256 signature of the request body, using your client +// secret as the signing key. This allows your app to verify that the +// notification really came from Nylas. +function verifyNylasRequest (req) { + const digest = crypto + .createHmac('sha256', config.get('NYLAS_CLIENT_SECRET')) + .update(req.rawBody) + .digest('hex') + return digest === req.get('x-nylas-signature') +} + +async function nylasWebhookCheck (req, res) { + // Nylas will check to make sure your webhook is valid by making a GET + // request to your endpoint with a challenge parameter when you add the + // endpoint to the developer dashboard. All you have to do is return the + // value of the challenge parameter in the body of the response. + return req.query.challenge +} + +let nylasWebhookInvocationId = 0 +async function nylasWebhook (req, res) { + // Verify the request to make sure it's actually from Nylas. + if (!verifyNylasRequest(req)) { + localLogger.error('Failed to verify nylas', 'nylasWebhook') + return res.status(401).send('X-Nylas-Signature failed verification 🚷 ') + } + + try { + // Nylas sent us a webhook notification for some kind of event, so we should + // process it! + const data = req.body.deltas + for (let i = 0; i < data.length; i++) { + if (eventProcessors[data[i].type]) { + nylasWebhookInvocationId += 1 + localLogger.debug(`Processing Nylas Webhook type: "${data[i].type}", object id: "${_.get(data[i], 'object_data.id')}", date: "${data[i].date ? moment.unix(data[i].date).utc().format() : 'na'}", data: ${JSON.stringify(data[i])}.`, `nylasWebhook #webhook-${nylasWebhookInvocationId}`) + await eventProcessors[data[i].type](data[i], nylasWebhookInvocationId) + } else { + localLogger.debug(`Ignoring Nylas Webhook type: "${data[i].type}", data: ${JSON.stringify(data[i])}.`, 'nylasWebhook') + } + } + } catch (e) { + localLogger.error(`Process nylas webhook failed with error: ${e.toString()}`, 'nylasWebhook') + } + + // 200 response tells Nylas your endpoint is online and healthy. + res.sendStatus(200) +} + +module.exports = { + nylasWebhook, + nylasWebhookCheck +} diff --git a/src/services/TeamService.js b/src/services/TeamService.js index 50cb2107..30bc40ec 100644 --- a/src/services/TeamService.js +++ b/src/services/TeamService.js @@ -399,6 +399,7 @@ async function getTeamJob (currentUser, id, jobId) { // find photo URLs for users const members = await helper.getMembers(_.map(users, 'handle')) const photoURLMap = _.groupBy(members, 'handleLower') + const hostMap = {} result.candidates = _.map(job.candidates, (candidate) => { const candidateData = _.pick(candidate, [ @@ -419,10 +420,31 @@ async function getTeamJob (currentUser, id, jobId) { if (photoURLMap[handleLower]) { candidateData.photo_url = photoURLMap[handleLower][0].photoURL } + if (candidateData.interviews && candidateData.interviews.length) { + _.map(candidateData.interviews, async interview => { + hostMap[interview.hostUserId] = true + }) + } return candidateData }) - } + // request host user details only one time if all interview are hosted by the same host + const hostUserDetails = await Promise.all(_.map(_.keys(hostMap), hostId => helper.getUserDetailsByUserUUID(hostId))) + _.map(_.keys(hostMap), (hostId, index) => { + hostMap[hostId] = hostUserDetails[index] + }) + + _.forEach(job.candidates, (candidate) => { + if (candidate.interviews && candidate.interviews.length) { + _.forEach(candidate.interviews, interview => { + const hostUserDetails = hostMap[interview.hostUserId] + interview.hostFirstName = hostUserDetails.firstName + interview.hostLastName = hostUserDetails.lastName + interview.hostHandle = hostUserDetails.handle + }) + } + }) + } return result } diff --git a/src/services/UserMeetingSettingsService.js b/src/services/UserMeetingSettingsService.js new file mode 100644 index 00000000..a8553d19 --- /dev/null +++ b/src/services/UserMeetingSettingsService.js @@ -0,0 +1,410 @@ +/** + * This service provides operations of UserMeetingSettings. + */ + +const _ = require('lodash') +const Joi = require('joi') +const config = require('config') +const helper = require('../common/helper') +const logger = require('../common/logger') +const errors = require('../common/errors') +const models = require('../models') +const { v4: uuid } = require('uuid') +const { + processCreateOrUpdate, + processUpdate +} = require('../esProcessors/UserMeetingSettingsProcessor') + +const UserMeetingSettings = models.UserMeetingSettings +const { Interviews: InterviewConstants, NylasVirtualCalendarProvider } = require('../../app-constants') +const esClient = helper.getESClient() +const NylasService = require('./NylasService') +const jwt = require('jsonwebtoken') +const { runExclusiveCalendarConnectionHandler } = require('../common/helper') + +/** + * Ensures user is permitted for the operation. + * + * @param {Object} currentUser the user who perform this operation. + * @param {String} userMeetingSettingsUserId the userId of the userMeetingSettings that currentUser is trying to access + * @throws {errors.ForbiddenError} + */ +async function ensureUserIsPermitted (currentUser, userMeetingSettingsUserId) { + if (!currentUser.hasManagePermission && !currentUser.isMachine) { + const userId = await helper.getUserId(currentUser.userId) + if (userId !== userMeetingSettingsUserId) { + throw new errors.ForbiddenError( + `userId: ${userId} cannot access userMeetingSettings ${userMeetingSettingsUserId}` + ) + } + } +} + +/** + * Strips unwanted data from the userMeetingSettings object + * + * Specifically, it removes any calendars with property 'isDeleted' set to true & + * it removes the properties 'accessToken' & 'accountId' from the calendars + * + * @param {object} userMeetingSettings + * @returns userMeetingSettings with modified data + */ +function stripUnwantedData (userMeetingSettings) { + if (userMeetingSettings.nylasCalendars) { + const availableCalendars = _.flatMap( + userMeetingSettings.nylasCalendars, + (item) => !item.isDeleted ? _.omit(item, ['accessToken', 'accountId', 'isDeleted']) : [] + ) + + userMeetingSettings.nylasCalendars = availableCalendars + } + + return userMeetingSettings +} + +function handleUserMeetingSettingsData (data, shouldNotStripUnwantedData) { + return shouldNotStripUnwantedData ? data : stripUnwantedData(data) +} + +/** + * Get UserMeetingsettings by userid + * @param {Object} currentUser the user who perform this operation. + * @param {String} userId the user id + * @param {Boolean} fromDb flag if query db for data or not + * @param {object} options { shouldNotStripUnwantedData: false } + * shouldNotStripUnwantedData - flag indicating if unwanted data should be stripped or not + * @returns {Object} the userMeetingSetting object + */ +async function getUserMeetingSettingsByUserId (currentUser, userId, fromDb, options = { shouldNotStripUnwantedData: false }) { + // check permission + await ensureUserIsPermitted(currentUser, userId) + if (!fromDb) { + try { + // get user meeting settings from ES + const userMeetingSettingsES = await esClient.get({ + index: config.esConfig.ES_INDEX_USER_MEETING_SETTINGS, + id: userId + }) + // extract interviews from ES object + const userMeetingSettings = _.get(userMeetingSettingsES, 'body._source') + if (userMeetingSettings) { + return handleUserMeetingSettingsData(userMeetingSettings, options.shouldNotStripUnwantedData) + } + throw new errors.NotFoundError(`The userMeetingSettings for userId=${userId} not found.`) + } catch (err) { + if (helper.isDocumentMissingException(err)) { + throw new errors.NotFoundError(`The userMeetingSettings for userId=${userId} not found.`) + } + logger.logFullError(err, { component: 'UserMeetingSettingsService', context: 'getInterviewByRound' }) + throw err + } + } + + // either ES query failed or `fromDb` is set - fallback to DB + logger.info({ component: 'InterviewService', context: 'getUserMeetingSettingsByUserId', message: 'try to query db for data' }) + + const userMeetingSettings = await UserMeetingSettings.findById(userId) + + return handleUserMeetingSettingsData(userMeetingSettings, options.shouldNotStripUnwantedData) +} +getUserMeetingSettingsByUserId.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + userId: Joi.string().uuid().required(), + fromDb: Joi.boolean(), + options: Joi.object().keys({ + shouldNotStripUnwantedData: Joi.boolean() + }) +}).required() + +/** + * Create UserMeetingSettings if it doesn't exist for user + * or updates existent records if it exists + * + * This method kind of merge provided data with existent + * + * @param {Object} currentUser current user object + * @param {Object} data data to sync + * @param {Object} data.id UserMeetingSettings id (user UUID) + * @param {Object} data.defaultAvailableTime default availability time to set + * @param {Object} data.defaultTimezone default timezone to set + * @param {Object} data.calendar calendar to add or update + * @param {Object} transaction transaction + * @returns {Object} existent or created UserMeetingSettings record + */ +async function syncUserMeetingsSettings (currentUser, data, transaction) { + // check permission + await ensureUserIsPermitted(currentUser, data.id) + + let userMeetingSettings = await UserMeetingSettings.findOne({ + where: { + id: data.id + } + }) + + // if UserMeetingSettings doesn't exist yet, then we crate it for the user + if (!userMeetingSettings) { + const entity = _.pick(data, ['id', 'defaultAvailableTime', 'defaultTimezone']) + + entity.createdBy = await helper.getUserId(currentUser.userId) + + if (data.calendar) { + entity.nylasCalendars = [data.calendar] + } + + // set empty array by default if not defined + if (!entity.defaultAvailableTime) { + entity.defaultAvailableTime = [] + } + + userMeetingSettings = await UserMeetingSettings.create(entity, { transaction: transaction }) + await processCreateOrUpdate(userMeetingSettings.toJSON()) + + // if UserMeetingSettings record already exists for the user we update it + } else { + const updatePayload = userMeetingSettings.toJSON() + + _.forEach(['defaultAvailableTime', 'defaultTimezone'], (updatedProp) => { + // we only update values if provided new values are non-null + // so we don't remove existent values + if (data[updatedProp]) { + updatePayload[updatedProp] = data[updatedProp] + } + }) + + updatePayload.updatedBy = await helper.getUserId(currentUser.userId) + + // add or update calendar if it was provided + if (data.calendar) { + const calendarIndexInUserMeetingSettings = _.findIndex(userMeetingSettings.nylasCalendars, { + // we only allow one calendar by the pair of email/accountProvider + email: data.calendar.email, + accountProvider: data.calendar.accountProvider + }) + + const updatedNylasCalendarsArray = _.map(userMeetingSettings.nylasCalendars || [], (item, index) => { + // process all other calendar, except the one wa are adding/updating + if (index !== calendarIndexInUserMeetingSettings) { + const updatedItem = { ...item } + + // if we are adding primary calendar, then make all other calendars non-primary + if (data.calendar.isPrimary) { + updatedItem.isPrimary = false + } + + // if we are adding not-Nylas calendar, mark all other not-Nylas calendars as removed, as we don't allow having multiple not-Nylas calendars + if (data.calendar.accountProvider !== NylasVirtualCalendarProvider && updatedItem.accountProvider !== NylasVirtualCalendarProvider) { + updatedItem.isDeleted = true + } + + return updatedItem + } + + // if we are updating existent calendar, then update it + return { ...item, ...data.calendar } + }) + + // add new calendar to the list updated list or just use updated list + updatePayload.nylasCalendars = calendarIndexInUserMeetingSettings === -1 ? [...updatedNylasCalendarsArray, data.calendar] : updatedNylasCalendarsArray + } + + const updateUserMeetingSettingsResponse = await UserMeetingSettings.update(updatePayload, { where: { id: userMeetingSettings.id }, returning: true, transaction }) + userMeetingSettings = updateUserMeetingSettingsResponse[1][0].dataValues + await processUpdate(userMeetingSettings) + } + + return userMeetingSettings +} +syncUserMeetingsSettings.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + data: { + id: Joi.string().uuid().required(), + defaultAvailableTime: Joi.array().items( + Joi.object({ + days: Joi.array().items(Joi.string().valid( + InterviewConstants.Nylas.Days.Monday, + InterviewConstants.Nylas.Days.Tuesday, + InterviewConstants.Nylas.Days.Wednesday, + InterviewConstants.Nylas.Days.Thursday, + InterviewConstants.Nylas.Days.Friday, + InterviewConstants.Nylas.Days.Saturday, + InterviewConstants.Nylas.Days.Sunday)).required(), + end: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required(), + start: Joi.string().regex(InterviewConstants.Nylas.StartEndRegex).required() + }) + ), + defaultTimezone: Joi.string().allow(null), + calendar: Joi.object().keys({ + id: Joi.string().required(), + calendarId: Joi.string().required().allow(null), + email: Joi.string().required(), + accountId: Joi.string().required(), + accessToken: Joi.string().required(), + accountProvider: Joi.string().required(), + isDeleted: Joi.bool().required(), + isPrimary: Joi.bool().required() + }) + }, + transaction: Joi.object() +}) + +/** + * Handle connect calendar callback + * + * @param {*} reqQuery containing state, code &/or error + * @returns The url that the user should be redirected to + */ +async function handleConnectCalendarCallback (reqQuery) { + // we force "calendar.created" webhook to wait until UserMeetingSettings records with "accountId" is created + // otherwise there could be a race condition and "calendar.created" this method started running, + // but UserMeetingSettings with "accountId" is not yet in DB + return runExclusiveCalendarConnectionHandler(async () => { + let errorReason = reqQuery.error + + // verifying jwt token for request query param - 'state' + const verifyQueryStateJwt = await jwt.verify(reqQuery.state, config.NYLAS_CONNECT_CALENDAR_JWT_SECRET, (err, decoded) => { + if (err) { + // if we cannot decode state, and there is already some error provided by Nylas, then return that error + if (errorReason) { + throw new Error(`Could not verify JWT token: ${errorReason}`) + } else { + throw new errors.UnauthorizedError(`Could not verify JWT token: ${JSON.stringify(err)}`) + } + } + + return decoded + }) + + // note userId is actually the UUID in the following line. not to confuse with other 'userId' + const { userId, redirectTo } = verifyQueryStateJwt + + let urlToRedirect + + // if Nylas sent error when connecting calendar + if (errorReason) { + urlToRedirect = `${redirectTo}&calendarConnected=false&error=${encodeURIComponent(errorReason)}` + return urlToRedirect + } + + try { + // getting user's accessToken from Nylas using 'code' found in request query + const { accessToken, accountId, provider, email } = await NylasService.getAccessToken(reqQuery.code) + // view https://developer.nylas.com/docs/api/#post/oauth/token for error response schema + if (!accessToken || !accountId) { + throw new errors.BadRequestError('Error getting access token for the calendar.') + } + + // When user connect their calendar to the Nylas the first time, it takes time for Nylas to sync that calendar into Nylas + // So if from the first attempt we haven't found the connected calendar, then we try several times after some delay + const primaryCalendar = await NylasService.getPrimaryCalendar(accessToken) + if (!primaryCalendar) { + logger.debug({ + component: 'InterviewService', + context: 'handleConnectCalendarCallback', + message: `Could not get connected calendar id for account "${accountId}" email "${email}" provider "${provider}". Proceeding without calendar id for now...` + }) + } + + const calendarId = primaryCalendar ? primaryCalendar.id : null + + const calendar = { + id: uuid(), // internal UUID + calendarId, // would be `null` if calendar was not retrieved from Nylas yet + accountId, + accessToken, + accountProvider: provider, + email, + isPrimary: true, + isDeleted: false + } + + // as a current user use the user who is connecting the calendar + // NOTE, that we cannot use `userId` because it's UUID, while in + // `currentUser` we need to have integer user id + const currentUser = _.pick(await helper.getUserDetailsByUserUUID(userId), ['userId', 'handle']) + + await syncUserMeetingsSettings( + currentUser, + { + id: userId, + calendar + } + ) + } catch (err) { + errorReason = encodeURIComponent(err.message) + } finally { + urlToRedirect = `${redirectTo}&calendarConnected=true` + + if (errorReason) { + urlToRedirect = `${redirectTo}&calendarConnected=false&error=${encodeURIComponent(errorReason)}` + } + } + + return urlToRedirect + }) +} + +handleConnectCalendarCallback.schema = Joi.object().keys({ + reqQuery: Joi.object() +}).required() + +/** + * Delete a calendar from UserMeetingSettings object + */ +async function deleteUserCalendar (currentUser, reqParams) { + // check permission + await ensureUserIsPermitted(currentUser, reqParams.userId) + + try { + const userMeetingSettings = await getUserMeetingSettingsByUserId(currentUser, reqParams.userId, false, { shouldNotStripUnwantedData: true }) + + const calendarToDelete = _.find(userMeetingSettings.nylasCalendars, (item) => item.id === reqParams.calendarId) + // error if no calendar found with the given id in request param + if (!calendarToDelete) { + throw new errors.NotFoundError(`Calendar with id "${reqParams.calendarId}" not found in UserMeetingSettings record.`) + } else { + let newPrimaryCalendarSet = false + // map all calenders and check if deleting calendar is primary + const updatedCalendars = _.map(userMeetingSettings.nylasCalendars, (item) => { + if (item.id === reqParams.calendarId) { + return { ...item, isPrimary: false, isDeleted: true } + } else { + // check if deleting primary calendar in this endpoint call & if another calendar is not already set as primary, + // if not, check the current iterating calendar is not already deleted + // then make the current iterating calendar as primary & set newPrimaryCalendarSet = true + if (calendarToDelete.isPrimary && !newPrimaryCalendarSet && !item.isDeleted) { + newPrimaryCalendarSet = true + return { ...item, isPrimary: true } + } + + return item + } + }) + + const updatePayload = { + ...userMeetingSettings, + nylasCalendars: updatedCalendars + } + + const updateUserMeetingSettingsResponse = await UserMeetingSettings.update(updatePayload, { where: { id: userMeetingSettings.id }, returning: true, transaction: null }) + const updatedUserMeetingSettings = updateUserMeetingSettingsResponse[1][0].dataValues + await processUpdate(updatedUserMeetingSettings) + } + } catch (err) { + throw new errors.BadRequestError(err.message) + } +} + +deleteUserCalendar.schema = Joi.object().keys({ + currentUser: Joi.object().required(), + reqParams: Joi.object().keys({ + userId: Joi.string().uuid().required(), + calendarId: Joi.string().required() + }).required() +}).required() + +module.exports = { + getUserMeetingSettingsByUserId, + syncUserMeetingsSettings, + handleConnectCalendarCallback, + deleteUserCalendar +} diff --git a/src/services/ZoomService.js b/src/services/ZoomService.js new file mode 100644 index 00000000..c14d0d1a --- /dev/null +++ b/src/services/ZoomService.js @@ -0,0 +1,175 @@ +const _ = require('lodash') +const axios = require('axios') +const jwt = require('jsonwebtoken') +const config = require('config') +const moment = require('moment') + +// get & parse all Zoom account credentials in an in-memory array +const ALL_ZOOM_ACCOUNTS = _.split(config.ZOOM_ACCOUNTS, ',') +let currentZoomAccountIndex = -1 + +/** + * Get Zoom account credentials from the list credentials by round robin + * + * @param {String} apiKey zoom account api key + * @returns { zoomAccountApiKey: string, zoomAccountApiSecret: string } zoom account credentials + */ +function getZoomAccountByRoundRobin (apiKey) { + if (ALL_ZOOM_ACCOUNTS.length === 0) { + throw new Error('No Zoom accounts is configured by "ALL_ZOOM_ACCOUNTS" environment variable.') + } + + if (apiKey) { + const zoomAccount = _.find(ALL_ZOOM_ACCOUNTS, a => _.startsWith(a, `${apiKey}:`)) + if (zoomAccount) { + const [zoomAccountApiKey, zoomAccountApiSecret] = _.split(zoomAccount, ':') + return { zoomAccountApiKey, zoomAccountApiSecret } + } else { + throw new Error(`No Zoom accounts is configured by "ALL_ZOOM_ACCOUNTS" environment matching the interview zoom meeting account ${apiKey}.`) + } + } + + const nextIndex = currentZoomAccountIndex + 1 + currentZoomAccountIndex = nextIndex >= ALL_ZOOM_ACCOUNTS.length ? 0 : nextIndex + + const [zoomAccountApiKey, zoomAccountApiSecret] = ALL_ZOOM_ACCOUNTS[currentZoomAccountIndex].split(':') + + return { + zoomAccountApiKey, + zoomAccountApiSecret + } +} + +/** + * Generate a Zoom JWT bearer access token + * + * @param {String} apiKey zoom account api key + * @returns JWT bearer access token for Zoom API access + */ +async function generateZoomJWTBearerAccessToken (apiKey) { + const { zoomAccountApiKey, zoomAccountApiSecret } = getZoomAccountByRoundRobin(apiKey) + + const accessToken = jwt.sign( + {}, + zoomAccountApiSecret, + { + algorithm: 'HS256', + expiresIn: 1500, + issuer: zoomAccountApiKey + } + ) + + return { accessToken, zoomAccountApiKey } +} + +/** + * Create Zoom meeting via Zoom API + * + * @param {Date} startTime the start time of the meeting + * @param {Integer} duration the duration of the meeting + * @returns Zoom API response + */ +async function createZoomMeeting (startTime, duration) { + const { accessToken, zoomAccountApiKey } = await generateZoomJWTBearerAccessToken() + + // POST request details in Zoom API docs: + // https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate + const res = await axios.post('https://api.zoom.us/v2/users/me/meetings', { + type: 2, + start_time: moment(startTime).utc().format(), + duration + }, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + + return { meeting: res.data, zoomAccountApiKey } +} + +/** + * Generate Zoom meeting link + * + * This method generates Zoom API JWT access token and uses it to + * create a Zoom meeting and gets the meeting link. + * + * @param {Date} startTime the start time of the meeting + * @param {Integer} duration the duration of the meeting + * @returns The meeting urls for the Zoom meeting + */ +async function generateZoomMeetingLink (startTime, duration) { + try { + const { meeting, zoomAccountApiKey } = await createZoomMeeting(startTime, duration) + + // learn more: https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate#responses + console.log(meeting.start_url, 'Zoom meeting link for host') + console.log(meeting.join_url, 'Zoom meeting link for participants') + + return { meeting, zoomAccountApiKey } + } catch (err) { + console.log(err.message) + throw err + } +} + +/** + * Update Zoom meeting + * + * @param {Date} startTime the start time of the meeting + * @param {Integer} duration the duration of the meeting + * @param {String} apiKey zoom account api key + * @param {Integer} zoomMeetingId zoom meeting id + * @returns {undefined} + */ +async function updateZoomMeeting (startTime, duration, zoomAccountApiKey, zoomMeetingId) { + const { accessToken } = await generateZoomJWTBearerAccessToken(zoomAccountApiKey) + // PATCH request details in Zoom API docs: + // https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingupdate + await axios.patch(`https://api.zoom.us/v2/meetings/${zoomMeetingId}`, { + start_time: moment(startTime).utc().format(), + duration + }, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) +} + +/** + * Cancel Zoom meeting via Zoom API + * + * @param {String} zoomAccountApiKey zoom account api key + * @param {Integer} zoomMeetingId zoom meeting id + * @returns {undefined} + */ +async function cancelZoomMeeting (zoomAccountApiKey, zoomMeetingId) { + const { accessToken } = await generateZoomJWTBearerAccessToken(zoomAccountApiKey) + // DELETE request details in Zoom API docs: + // https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingdelete + await axios.delete(`https://api.zoom.us/v2/meetings/${zoomMeetingId}`, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) +} + +/** + * Get Zoom meeting via Zoom API + * + * @param {String} zoomAccountApiKey zoom account api key + * @param {Integer} zoomMeetingId zoom meeting id + * @returns {undefined} + */ +async function getZoomMeeting (zoomAccountApiKey, zoomMeetingId) { + const { accessToken } = await generateZoomJWTBearerAccessToken(zoomAccountApiKey) + // GET request details in Zoom API docs: + // https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meeting + const res = await axios.get(`https://api.zoom.us/v2/meetings/${zoomMeetingId}`, { + headers: { + Authorization: `Bearer ${accessToken}` + } + }) + return res.data +} + +module.exports = { generateZoomMeetingLink, updateZoomMeeting, cancelZoomMeeting, getZoomMeeting } diff --git a/test/unit/WorkPeriodPaymentService.test.js b/test/unit/WorkPeriodPaymentService.test.js index b860bd22..24f236d8 100644 --- a/test/unit/WorkPeriodPaymentService.test.js +++ b/test/unit/WorkPeriodPaymentService.test.js @@ -32,6 +32,7 @@ describe('workPeriodPayment service test', () => { it('create work period success', async () => { const stubWorkPeriodFindById = sinon.stub(models.WorkPeriod, 'findOne').callsFake(async () => testData.workPeriodPayment01.workPeriodWithPayments) const stubUpdateWorkPeriod = sinon.stub(testData.workPeriodPayment01.workPeriodWithPayments, 'update').callsFake(async () => testData.workPeriodPayment01.workPeriodUpdateResponse) + sinon.stub(commonData.ESClient, 'search').callsFake(async () => testData.workPeriodPayment01.workPeriodUpdateESSearchResponse) const response = await service.createWorkPeriodPayment(commonData.currentUser, testData.workPeriodPayment01.request) expect(stubGetUserId.calledOnce).to.be.true expect(stubEnsureWorkPeriodById.calledOnce).to.be.true diff --git a/test/unit/common/CommonData.js b/test/unit/common/CommonData.js index 2653e732..54436356 100644 --- a/test/unit/common/CommonData.js +++ b/test/unit/common/CommonData.js @@ -13,7 +13,13 @@ const userWithManagePermission = { const regularUser = { userId: '222' } -const ESClient = {} +const ESClient = { + create: () => {}, + update: () => {}, + delete: () => {}, + search: () => {} +} + module.exports = { currentUser, UserTCConnCopilot, diff --git a/test/unit/common/WorkPeriodPaymentData.js b/test/unit/common/WorkPeriodPaymentData.js index 67322137..f9cbc4b4 100644 --- a/test/unit/common/WorkPeriodPaymentData.js +++ b/test/unit/common/WorkPeriodPaymentData.js @@ -118,6 +118,18 @@ const workPeriodPayment01 = { paymentStatus: 'in-progress', updatedAt: '2021-06-13T18:25:08.492Z' }, + workPeriodUpdateESSearchResponse: { + body: { + hits: { + hits: [ + { _id: 'something' } + ], + total: { + value: 'something' + } + } + } + }, workPeriodUpdateRequest: { daysPaid: 5, paymentTotal: 12.6,